Add index benchmarks against a generated 50k-row indexed table#302
Merged
Conversation
The repository fixtures are a handful of rows, so index benchmarks need generated data: BenchmarkTableGenerator writes a 50,000-row DBF plus a matching compound index (two tags: unique integer IDs and duplicated character codes) using the simplest structure the library's strict CDX reader accepts - uncompressed leaf entries, max-key interior entries, and a two-tag directory. Generated files are verified for index/scan result equivalence through the public API before anything is measured. IndexQueryBenchmarks pairs the same SQL with UseIndexes on and off: equality seek 459x faster (50us vs 23ms), range scan 233x, character seek 141x, top-10 descending order 20x, filtered COUNT(*) 24x, and the whole-table COUNT(*) status scan cuts allocations from 16.8MB to 10KB. Results recorded in benchmarks.md. The benchmarks project now references the published DbfDataReader 2.1.0 package. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
….0 results Recreates the Sylvan / NDbf / DbfDataReader comparison in the style of MarkPflug/Benchmarks (reading every field of every record of the tl_2019_01_place census fixture), with the same method names as the historical v0.5.x tables. The DbfDataReader package version is now an MSBuild property (-p:DbfDataReaderVersion=x.y.z) so any release can be benchmarked; the 2.x-only index benchmarks are excluded from compilation for 1.x versions. A project README documents the commands. benchmarks.md gains v1.1.0 and v2.1.0 comparison sections: the sequential read path is unchanged between the two (~1.15x NDbf, identical allocations), confirming the SQL and index features are additive, and both improve markedly on the v0.5.x-era ratios. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Adds benchmarks demonstrating what automatic index use (v2.0.0–v2.1.0) buys, restores the historical cross-library comparison, and makes the benchmarked DbfDataReader package version switchable — everything measured against published packages (the project keeps its benchmark-the-release philosophy).
Cross-library comparison (v1.1.0 and v2.1.0 sections in benchmarks.md)
Recreates the Sylvan / NDbf / DbfDataReader comparison in the style of MarkPflug/Benchmarks — same method names as the old v0.5.x tables — reading every field of every record of the
tl_2019_01_placecensus fixture. The package version is an MSBuild property, so any release is one flag away:Findings: the sequential read path is unchanged from 1.1.0 to 2.1.0 (~1.15× NDbf, identical allocations) — the whole SQL/typed-query/index feature set is additive — and both improve markedly on the 0.5.x-era ratios (1.8–1.9× with 4× allocations). The 2.x-only index benchmarks are excluded from compilation when benchmarking 1.x. A project README documents the commands.
Index benchmarks
The repository fixtures are 3–16 rows — useless for index benchmarks — so
BenchmarkTableGeneratorwrites a 50,000-row DBF plus a matching compound index: the CDX writer produces the simplest structure the library's strict reader accepts (uncompressed leaf entries, max-key interior entries, sibling-linked levels, a two-tag directory), with tags onID(unique integers, exercising the #298 key transform) andCODE(character keys, ~100 rows per value). Before anything is measured,GlobalSetupverifies through the public API that indexed and scanned executions return identical rows for every benchmarked shape — a wrong writer fails the run rather than producing pretty-but-false numbers.Results (Apple M3 Max, .NET 10, ShortRun; full tables in benchmarks.md)
top 10 … order by ID desccount(*)filtered (10k rows)count(*)all rowsThe last row is the honest one: a whole-table count still reads every record, so the win is modest in time but ~1,600× in allocations — value parsing is what it skips.
🤖 Generated with Claude Code