A zero-copy read view over a packed numeric column — [PND-PROCCOL].
The counterpart to columnBuffers, which copies because its
result crosses a thread. This one borrows: values and bits are
subarrays of the column's own storage, valid only while the memo
that produced the column holds it. Read, never retain.
undefined for anything not packed numeric — a string column, or a
value that arrived boxed — so a caller keeps its slow path.
Why a view rather than scan
Measured folding a max over 500k cells:
read path
ms
boxed (number|undefined)[]
0.91
Column.scan()
4.27
buffer + bitmap
0.96
The columnar form is not faster to read — a buffer walk only
reaches parity with the boxed array, and scan is 4.7× slower than
either because it takes a callback per cell. The case for it is that
it does not allocate: no Array of 500k boxed slots per version,
and nothing at all for a fold like latest, which reads one cell.
Core's design principles recommend scan as the columnar read path,
which is worth revisiting on this evidence.
A zero-copy read view over a packed numeric column — [PND-PROCCOL].
The counterpart to columnBuffers, which copies because its result crosses a thread. This one borrows:
valuesandbitsaresubarrays of the column's own storage, valid only while the memo that produced the column holds it. Read, never retain.undefinedfor anything not packed numeric — a string column, or a value that arrived boxed — so a caller keeps its slow path.Why a view rather than
scanMeasured folding a max over 500k cells:
(number|undefined)[]Column.scan()The columnar form is not faster to read — a buffer walk only reaches parity with the boxed array, and
scanis 4.7× slower than either because it takes a callback per cell. The case for it is that it does not allocate: noArrayof 500k boxed slots per version, and nothing at all for a fold likelatest, which reads one cell. Core's design principles recommendscanas the columnar read path, which is worth revisiting on this evidence.