Skip to content

Glue: JSON text as an intermediate on bulk and per-row paths, ten ranked candidates (none timed yet) #388

Open

Description

@tae898

Several paths of both wheels still put data into JSON text on the Java side and parse it again in Python. For bulk, typed or wide data that costs a text format, a parse and one dict per row, and the columnar routes of #331, #335 and #383 show what the binary route buys. I went through every place of the glue that uses JSON as an intermediate (a code read of main at 65e7c8f: 42 uses classified from 338 grep hits in 29 files) to see which ones are worth removing.

None of this is timed. Every cost named here is a number of crossings or per-row work read from the code, so nothing below is a speed claim. Each item gets its own measured table and a pre-registered A/B (ABBA, A/A control, against the released wheel) before its pull request, as for #382 to #385.

17 of the 42 uses sit on a bulk or per-row path. Ten are worth the work, ranked by how much data goes through them and how small the fix is:

rank wheel site on main what the JSON carries when replacement rebuild check first
1 JVM src/arcadedb/core.py:948 insert_many rows as one JSON text per chunk (10,000 rows), tagged values for date, datetime, Decimal, bytes, numpy and pandas scalars; float vectors... per chunk of 10,000 rows route homogeneous chunks through rows_to_columns and DocumentBatcher.insertColumns (exists); keep JSON for shapes columns cannot carry none (PY) yes, plus a stored-type differential test
2 native src/arcadedb/_native/database.py:648 row count (count() walks the whole result) per count() call; O(rows) arcadedb_n_count returning a long; PY partial: count len(batch) without building NativeResult native image for full no, the loop is the evidence
3 native native/src/main/java/org/humemai/nativelib/ArcadeNative.java:205 transaction state {ok, active, depth, commits} per begin, commit, rollback, is_transaction_active, stack mark return one long (active bit, depth, commits packed) from arcadedb_n_tx native image no, counts are the evidence; measure only to size the win
4 native src/arcadedb/_native/colframes.py:160 head of a columnar read: up to 256 JSON-decoded rows re-packed into a frame with a Python-written JSON header once per to_arrow/to_columns/to_dataframe/to_polars call ask Java for frame 1 directly (arcadedb_n_next_col from the first call), retire _head_frame native image + PY yes
5 native src/arcadedb/_native/schema_objects.py:331 approximate vector search: the query vector as a JSON list of d numbers, hits as a JSON list of [rid, score] per search arcadedb_n_vindex_bin taking a float32 pointer and count; hits as one packed buffer native image yes: how often approximate is called in the benchmark lanes
6 native native/src/main/java/org/humemai/nativelib/NativeCodec.java:83 query and command result rows (property dict per row, plus a meta array per row: rid, type, v/e/d) first reply up to 256 rows (_FIRST_BATCH), then 2048 rows per crossing (_NEXT_BATCH); per... binary row batches (frame per batch decoded to column lists, rows built by zip) for typed or wide results; keep JSON for narrow plain rows native image yes: json.loads is C, zip-of-columns is Python per row
7 native src/arcadedb/_native/extras.py:193 GraphBatch create_vertices: rows as JSON, RIDs back as a JSON list of text per chunk (commit_every rows) frame (insert_cols layout) in, packed long[] of RIDs back native image yes
8 native src/arcadedb/_native/extras.py:575 async create_record: one JSON op {type, kind, props} per record, plus callbacks per record a create_records batch entry taking a frame; or buffer in Python and use insert_parallel native image no, crossings are the evidence
9 JVM src/arcadedb/graph_batch.py:262 GraphBatch create_vertices: rows as JSON text, RIDs back as one ';'-joined text per chunk (_BULK_CHUNK rows) a ColumnBatcher-style typed insert for vertices (DocumentBatcher.insertColumns already builds vertex types) none (PY) or bridge jar yes
10 both native/src/main/java/org/humemai/nativelib/ColumnFrames.java:322 the json column kind inside binary column frames (nested lists, maps, RIDs, embedded documents, mixed-type columns): one tagged JSON array per column per frame, per cell of such a column add column kinds: rid (two int64), list of int64/float64 (ragged offsets), keep json for the rest native image and bridge jar yes

Also found, not in the first audit: the query vector of an approximate vector search crosses as a JSON list (rank 5), and the json cell kind inside binary frames (rank 10) makes RID, list and map columns go through text. arcadedb_command in ArcadeLib.java has no Python caller and can go.

What stays: error replies, control and configuration messages, frame headers and column specs (once per call or per failure), statement parameters (small, and float32 vectors already go binary), the JVM to_dict and to_list reads where the code comments say JSON is the cheaper container on JPype (only the object hook is removable, that is #382), and the shapes that a column cannot carry (widen the columnar path first). The JSON that a caller asks for (to_json_list, iter_json_batches, to_json) never goes.

Rank 3 is #384, and rank 4 is the second part of #381. The rest has no pull request yet. I take them in the order of the table, the first ones needing no native rebuild, and I post the A/B of each here.

Related: #315, #381.

Activity

  1. self-assigned this
    on Nov 14, 2026
  2. added
    pythonPull requests that update python code
    performanceSpeed or memory of the bindings, with a measurement
    nativeThe arcadedb package (native library build)
    jvmThe arcadedb-jvm package (JPype build)
    on Nov 14, 2026
  3. added this to the 26.12.1 milestone on Nov 14, 2026
  4. 11 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

jvmThe arcadedb-jvm package (JPype build)nativeThe arcadedb package (native library build)performanceSpeed or memory of the bindings, with a measurementpythonPull requests that update python codevectorVector indexes and find_nearest

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions