Problem statement
PR #245 optimizes the NBCROW null bitmap read path (allocate-once via zeroed_bitmap, then reuse the allocation across rows via a scratch cache). Review feedback on that PR — reasonably — asked whether the second half is measured to matter.
There is no benchmark today that can answer that. The relevant number is end-to-end rows/sec on a row-heavy scan, not read_nbc_bitmap in isolation, and the effect is highly shape-dependent:
- All-fixed-width rows (INT/BIGINT/DATETIME2/FLOAT/BIT) with more than 8 columns: nothing else in the row path allocates, so the null bitmap is 100% of per-row allocator traffic. This is where the scratch cache should show up.
- Text-heavy rows (NVARCHAR/VARBINARY): every string cell already allocates, so removing one allocation out of ~4 is expected to be in the noise.
The theoretical delta is also narrower than an allocation count suggests, because Arc::get_mut goes through is_unique(), which is a compare_exchange. Per row it is roughly:
|
per row |
| allocate each row |
1 malloc + 1 free + 1 CAS + 1 atomic decrement |
| reuse the allocation |
1 CAS + 1 atomic increment + 1 atomic decrement |
So this needs measuring rather than reasoning about.
Proposed solution
Add an NBCROW row-throughput benchmark that measures the whole row path against mssql-mock-tds, not a single function:
- Parameterize over column count (e.g. 4 / 16 / 64) so the bitmap crosses the 1-byte, 2-byte, and 8-byte boundaries.
- Parameterize over column shape: all-fixed-width vs. text-heavy vs. mixed.
- Report rows/sec and allocations per row. A counting global allocator in the bench harness makes the allocation claim directly assertable rather than inferred.
- Include a NULL-density axis, since NBCROW is only emitted when the server sees nulls.
This should land alongside the broader row-path allocation work rather than as a one-off, so the same harness can cover the other allocations on the path (row buffers, column value decoding) instead of being NBCROW-specific.
Affected crate
mssql-tds
Alternatives considered
A criterion microbenchmark over read_nbc_bitmap alone. Rejected: it would measure Arc::get_mut against malloc in a tight loop with a hot allocator free-list and no surrounding work, which is not representative of the real path and risks producing a confidently wrong number in either direction.
Additional context
Context and the full trade-off discussion: #245 (see the review discussion with David Engel (@David-Engel)).
Problem statement
PR #245 optimizes the NBCROW null bitmap read path (allocate-once via
zeroed_bitmap, then reuse the allocation across rows via a scratch cache). Review feedback on that PR — reasonably — asked whether the second half is measured to matter.There is no benchmark today that can answer that. The relevant number is end-to-end rows/sec on a row-heavy scan, not
read_nbc_bitmapin isolation, and the effect is highly shape-dependent:The theoretical delta is also narrower than an allocation count suggests, because
Arc::get_mutgoes throughis_unique(), which is acompare_exchange. Per row it is roughly:So this needs measuring rather than reasoning about.
Proposed solution
Add an NBCROW row-throughput benchmark that measures the whole row path against
mssql-mock-tds, not a single function:This should land alongside the broader row-path allocation work rather than as a one-off, so the same harness can cover the other allocations on the path (row buffers, column value decoding) instead of being NBCROW-specific.
Affected crate
mssql-tds
Alternatives considered
A criterion microbenchmark over
read_nbc_bitmapalone. Rejected: it would measureArc::get_mutagainstmallocin a tight loop with a hot allocator free-list and no surrounding work, which is not representative of the real path and risks producing a confidently wrong number in either direction.Additional context
Context and the full trade-off discussion: #245 (see the review discussion with David Engel (@David-Engel)).