Experiment 082: Isolate message-graph benchmark for result payloads

Date: 2026-04-20

Status: Rejected (optimization hypothesis disproven; benchmark harness kept)

Problem

After several result-storage experiments, it was still unclear whether the

remaining headroom lived in:

Those phases were too entangled in normal db.select() benchmarking to

attribute wins cleanly. We needed a benchmark that isolated the message

graph itself.

Hypothesis

If the current ResultSet / Row shape is not near-optimal, then an

isolated hand-off benchmark should show a clearly better alternative graph

shape for one or both of:

Candidate graphs:

  1. Current ResultSet
  2. Fully materialized row maps
  3. Binary row facade

Measured separately:

Approach

Added reusable benchmark harness:

The harness:

This gives a direct answer to “is the result object shape itself still a

frontier?” without conflating decode cost.

Results

Artifacts:

The AOT run is the most important signal because it matches shipped

Flutter runtime behavior.

AOT examples

Numeric-heavy, SendPort.send, 1000 rows

ShapeTransfer p50Consume p50Total p50
current ResultSet0.013 ms0.091 ms0.104 ms
materialized maps0.165 ms0.157 ms0.316 ms
binary row facade0.013 ms0.396 ms0.409 ms

Mixed-schema, SendPort.send, 10000 rows

ShapeTransfer p50Consume p50Total p50
current ResultSet0.275 ms0.769 ms1.048 ms
materialized maps2.021 ms1.266 ms3.345 ms
binary row facade0.080 ms2.482 ms2.566 ms

Mixed-schema, Isolate.exit, 10000 rows

ShapeTransfer p50Consume p50Total p50
current ResultSet1.816 ms0.781 ms2.580 ms
materialized maps4.882 ms1.074 ms6.114 ms
binary row facade2.063 ms2.370 ms4.397 ms

Decision

Rejected as an optimization direction, but the benchmark harness should be

kept.

The main result is that the current ResultSet / Row shape is already

very strong for the shipped select() contract:

Both alternatives we tested lost on end-to-end total time once actual row

consumption was included:

This is a useful negative result. It means future performance work should

not keep trying to replace generic select() result objects unless the

API contract changes.

More promising directions from here are:

The harness remains valuable because it gives a clean way to test any

future result-graph idea without conflating SQLite decode, isolate

transport, and row consumption.