Skip to content

Benchmark NBCROW row throughput to validate the null bitmap allocation optimization #282

Description

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)).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions