Skip to content

refactor(hashing): name the algorithm in the unsigned hashers - #355

Merged
marius-bughiu merged 6 commits into
mainfrom
fix/issue-297-unsigned-hasher-names
Aug 9, 2026
Merged

refactor(hashing): name the algorithm in the unsigned hashers#355
marius-bughiu merged 6 commits into
mainfrom
fix/issue-297-unsigned-hasher-names

Conversation

@marius-bughiu

@marius-bughiu marius-bughiu commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Closes #297.

The defect

The bare UIntNN Hasher name mapped to opposite tiers of the escalation ladder in the two unsigned widths:

Type What it actually was Signed peer
UInt32Hasher the cheapest mixer — XOR-fold, key ^ (key >> 16) Int32WangNaiveHasher
UInt64Hasher the strongest mixer — Murmur3 fmix64 finalizer Int64Murmur3Hasher

Hasher selection is the main knob this library exposes and callers pick by analogy across key widths — that is how the rest of the surface is designed to be read. Someone who benchmarked on uint with UInt32Hasher and then moved to ulong keys with UInt64Hasher silently changed hash strength, not just key width, and nothing in the name said so. The signed families never had the problem because they name the algorithm in the type.

The package README already described the scheme this PR makes true: "*WangNaiveHasher, *WangHasher, *Murmur3Hasher across int / long / uint / ulong" — a claim that was false for two of the twelve slots.

What ships

Option 1 of the issue — rename for explicitness, old names kept as [Obsolete] aliases for a release.

  • UInt32WangNaiveHasher and UInt64Murmur3Hasher are the new names. Same hash values.
  • UInt32Hasher / UInt64Hasher are [Obsolete] (warning, not error) and forward to the new types rather than repeating the mixer, so the two cannot drift.
  • UInt64Hasher keeps IHashProvider64<ulong>. Dropping it would have pushed an existing sketch back to the 2^32 entropy floor IHashProvider64<T> exists to escape — silently, as a side effect of a naming change.
  • The identity tier is still signed-only, and that is an open gap, not a decision. The first draft of this PR claimed an unsigned caller reaches the zero-work floor with a cast and pinned that with a test. Review caught that the premise is false for the primary use case: the collections constrain THasher to IHashProvider<TKey> and invoke Hash internally, so Int32IdentityHasher cannot serve a CelerityDictionary<uint, …> and there is no call site to cast in — uint / ulong-keyed collections have no reachable zero-work tier at all. The claim and its test were removed; the gap is filed as No identity hasher for uint / ulong — the zero-work tier is unreachable from a hasher-parameterized collection #357 rather than settled inside a rename.

Compatibility: additive and source-compatible. Existing code compiles with a CS0618 warning pointing at the replacement; the type forwarders for the aliases are unchanged and two new ones were added, so binary compatibility is preserved on both. EnablePackageValidation runs against the 2.5.0 baseline on every pack.

Parity rollout

Collection / APIsrc/Celerity.Hashing/UInt32WangNaiveHasher.cs, UInt64Murmur3Hasher.cs (new); UInt32Hasher.cs, UInt64Hasher.cs (now aliases); cross-reference fixes in UInt32WangHasher.cs, UInt32Murmur3Hasher.cs, UInt64WangHasher.cs, UInt64WangNaiveHasher.cs; two new entries in src/Celerity/TypeForwarders.cs.

Dedicated testsUInt32WangNaiveHasherTests / UInt64Murmur3HasherTests mirror the suites the old names carried. UInt32HasherTests / UInt64HasherTests are now alias tests: the original anchor vectors (so the alias's behaviour is pinned, not just its delegation), agreement with the replacement across a key sweep, the [Obsolete] attribute, and — for UInt64Hasher — that it still implements IHashProvider64<ulong>.

Cross-cutting testsHashProvider64ContractTests (the family roster) gains UInt64Murmur3Hasher and keeps UInt64Hasher, with reduction and signed-peer agreement rows for both. New IntegerHasherFamilyNamingTests is the regression guard for the drift itself: every width ships the same three named mixing tiers, no live integer hasher carries a bare width-only name, and the unsigned/signed bit-pattern agreement is pinned — including the one pair that deliberately diverges, the 32-bit naive fold, whose >> 16 is arithmetic on int and logical on uint (-1 folds to 0; 0xFFFFFFFF folds to 0xFFFF0000). It deliberately says nothing about the identity tier (see above).

Benchmarks — no new class: this is a rename, not a new algorithm, and IntegerHasherBenchmark is already registered in Program.cs. Its arms were renamed with the types — UInt32_DefaultUInt32_WangNaive, UInt64_DefaultUInt64_Murmur3, UInt64_Default_Hash64UInt64_Murmur3_Hash64 — which is the point: the dashboard now labels a uint / ulong bar with its algorithm exactly like the int / long bars. The renamed rows start a new series on the tracked chart; the old _Default series stops at this commit. HashQualityReportRunner follows, and its ulong block is reordered cheapest-first to match the other three widths.

Dashboard — no COLLECTIONS entry applies (that array is collections-only; hashers are regex-parsed out of the benchmark names by parseHasher, and the shape {Type}_{Hasher} is unchanged). scripts/check_dashboard_coverage.js and scripts/check_doc_anchors.js both pass locally. web/index.html names no individual hasher, so no ship card changes.

Docsdocs/api/hashing.md: full sections for both new types (algorithm, zero-mapping note, the arithmetic-vs-logical-shift caveat), the IHashProvider64 roster table, the "choosing a hasher" table, the measured-distribution table (reordered to the ladder), and a new Deprecated hasher aliases section with a migration snippet. docs/migration.md: a rename section that also flags the substantive question — code that picked both by analogy may not have been asking for what it thought. Plus README.md, docs/README.md, docs/aot.md, and src/Celerity.Hashing/README.md.

CHANGELOG[Unreleased] gains one ### Added bullet (the types, pointing at the migration guide), one ### Changed bullet (the benchmark arm rename, which starts a new dashboard series) and a new ### Deprecated section. Condensed on review: the section is lifted verbatim as the release body and this repo has already had a release half-fail on an over-long one, so the rollout detail lives here instead.

ROADMAP — a done entry under 2.4.0's "Identified after the review" group, recording the IHashProvider64 call and the open identity gap.

Review rounds

Three Copilot rounds; every finding was acted on. Round 1 (6 comments) caught a heading inserted mid-section that stranded DefaultHasher<T>'s closing paragraph, an "for one release" lifecycle phrase contradicting the [Obsolete] message, legacy test-method names in the new suites, and CHANGELOG verbosity. Round 2 and 3 had no inline comments but real findings in the suppressed block: the false unsigned-identity premise above, and an IHashProvider64 roster table that had dropped the still-implementing UInt64Hasher alias. Fixed in 3f3ac5a, 7bbc7c3 and 2730330.

Test plan

  • dotnet build — clean, 0 warnings.
  • dotnet test5650 passed, 0 failed on each of net8.0 / net9.0 / net10.0, plus the three showcase test projects.
  • Coverage (coverage.runsettings, net10.0): Celerity.Hashing at 100% line / 100% branch. The obsolete aliases are excluded automatically by coverlet's default ExcludeByAttribute, and are covered by tests regardless.
  • AOT smoke test binary runs clean; it exercises both new types through CelerityDictionary and asserts each alias agrees with its replacement, so ILC still compiles the alias instantiations.
  • node scripts/check_doc_anchors.js and --self-test — 574 links resolve.
  • node scripts/check_dashboard_coverage.js — 155 cards across 47 collections.
  • CI matrix (ubuntu / windows / macos × net8.0 / net9.0 / net10.0), the coverage gate, aot-publish, doc-anchors, and pack with EnablePackageValidation against the 2.5.0 baseline.
  • gh-pages dashboard refresh on merge to main — the hasher section should show WangNaive / Murmur3 labels on the uint and ulong groups where it previously showed Default.

🤖 Generated with Claude Code

The bare `UIntNN Hasher` name meant opposite tiers of the escalation ladder in
the two unsigned widths: `UInt32Hasher` was the cheap XOR-fold, `UInt64Hasher`
the strong Murmur3 fmix64 finalizer. Hasher choice is the main knob this library
exposes and callers pick by analogy across widths, so moving from uint to ulong
keys silently changed hash strength, not just key width. The signed families
never had the problem because they name the algorithm in the type.

`UInt32WangNaiveHasher` and `UInt64Murmur3Hasher` now ship. The old names remain
as [Obsolete] aliases that forward to them rather than repeating the mixer, so
the pairs cannot drift and no hash value moved. `UInt64Hasher` keeps its
IHashProvider64<ulong> implementation — dropping it would push an existing
sketch back to the 2^32 entropy floor as a side effect of a naming change.

`IntegerHasherFamilyNamingTests` is the regression guard: it fails on a new
bare-named integer hasher or a width missing a tier, records the signed-only
identity tier as deliberate, and pins the one unsigned/signed pair that is not
bit-identical (the 32-bit naive fold, arithmetic shift vs logical).

Closes #297.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings August 9, 2026 01:26
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Coverage

Metric Value
Line 100% (12634/12634)
Branch 100% (5188/5188)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Renames unsigned integer hashers to expose their algorithms while preserving compatibility through obsolete aliases.

Changes:

  • Adds UInt32WangNaiveHasher and UInt64Murmur3Hasher.
  • Adds compatibility, contract, AOT, and parity tests.
  • Updates benchmarks, documentation, migration guidance, and release notes.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Celerity/TypeForwarders.cs Forwards new hasher types and aliases.
src/Celerity.Tests/Hashing/UInt64Murmur3HasherTests.cs Tests the renamed 64-bit hasher.
src/Celerity.Tests/Hashing/UInt64HasherTests.cs Tests deprecated alias compatibility.
src/Celerity.Tests/Hashing/UInt32WangNaiveHasherTests.cs Tests the renamed 32-bit hasher.
src/Celerity.Tests/Hashing/UInt32HasherTests.cs Tests deprecated alias compatibility.
src/Celerity.Tests/Hashing/IntegerHasherFamilyNamingTests.cs Guards family naming and parity.
src/Celerity.Tests/Hashing/HashProvider64ContractTests.cs Extends 64-bit provider contracts.
src/Celerity.Hashing/UInt64WangNaiveHasher.cs Updates cross-references.
src/Celerity.Hashing/UInt64WangHasher.cs Updates cross-references.
src/Celerity.Hashing/UInt64Murmur3Hasher.cs Adds the named Murmur3 implementation.
src/Celerity.Hashing/UInt64Hasher.cs Converts the old type into an alias.
src/Celerity.Hashing/UInt32WangNaiveHasher.cs Adds the named XOR-fold implementation.
src/Celerity.Hashing/UInt32WangHasher.cs Updates cross-references.
src/Celerity.Hashing/UInt32Murmur3Hasher.cs Updates cross-references.
src/Celerity.Hashing/UInt32Hasher.cs Converts the old type into an alias.
src/Celerity.Hashing/README.md Documents explicit hasher naming.
src/Celerity.Benchmarks/IntegerHasherBenchmark.cs Renames benchmark series.
src/Celerity.Benchmarks/HashQualityReportRunner.cs Updates and reorders report rows.
src/Celerity.AotSmokeTest/Program.cs Exercises new names and aliases under AOT.
ROADMAP.md Records the completed naming decision.
README.md Updates hasher selection guidance.
docs/README.md Updates the hashing API index.
docs/migration.md Adds migration instructions.
docs/api/hashing.md Documents new types and aliases.
docs/aot.md Updates AOT coverage documentation.
CHANGELOG.md Records additions and deprecations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/api/hashing.md
Comment thread src/Celerity.Hashing/UInt32WangNaiveHasher.cs Outdated
Comment thread src/Celerity.Hashing/UInt64Murmur3Hasher.cs Outdated
Comment thread src/Celerity.Tests/Hashing/UInt32WangNaiveHasherTests.cs Outdated
Comment thread src/Celerity.Tests/Hashing/UInt64Murmur3HasherTests.cs Outdated
Comment thread CHANGELOG.md Outdated
Four fixes from the first review round:

- The "Deprecated hasher aliases" heading was inserted mid-section, stranding
  DefaultHasher<T>'s closing paragraph under it so its "It" referred to the
  wrong subject. Moved below that paragraph.
- The two new hashers' remarks promised removal "for one release" while the
  Obsolete message and the migration guide say "a future major version".
  Aligned on the latter, in the remarks and in ROADMAP.md.
- Renamed the new suites' methods to Method_ShouldExpectedBehavior_WhenCondition.
  They had mirrored the legacy names of the files they replaced; mirroring the
  coverage is the point, not mirroring stale names.
- Condensed the CHANGELOG entry. The section becomes the release body verbatim
  and this repo has already hit GitHub's size limit once, so the test and doc
  rollout bullets fold into the API bullet, which now points at the migration
  guide instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 01:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/Celerity.Tests/Hashing/IntegerHasherFamilyNamingTests.cs:74

  • This “adds nothing” premise does not hold for the library's primary generic use case. CelerityDictionary<TKey, ..., THasher> requires THasher : IHashProvider<TKey> (CelerityDictionary.cs:19-21), so Int32IdentityHasher cannot be supplied for a uint collection and there is no caller-side cast to insert—the collection invokes Hash internally. The negative assertions therefore freeze out a useful zero-work IHashProvider<uint>/IHashProvider<ulong> API for an unrelated naming regression. Remove this absence contract (and the matching ROADMAP claim); the test should only pin the three algorithm-named mixing tiers relevant to this PR.
        // The zero-work floor is reached from an unsigned key with a free cast at the call
        // site (`new Int32IdentityHasher().Hash((int)u)`), so a UInt32IdentityHasher would be
        // a type that adds nothing. Recorded here rather than left to be rediscovered as a gap.

ROADMAP.md:244

  • The claim that an unsigned identity hasher “adds nothing” is inaccurate for collection consumers. The collections constrain THasher to IHashProvider<TKey>, so Int32IdentityHasher : IHashProvider<int> cannot hash a CelerityDictionary<uint, ...>; users cannot insert the suggested cast because hashing occurs inside the collection. Remove this design conclusion (and its new negative test) or document a rationale that accounts for generic collection usage.
- The bare `UIntNN Hasher` name meant opposite tiers of the escalation ladder in the two unsigned widths: `UInt32Hasher` was the cheap XOR-fold while `UInt64Hasher` was the strong Murmur3 `fmix64` finalizer, so a caller who benchmarked on `uint` and then moved to `ulong` keys by analogy silently changed hash *strength*, not just key width. Hasher selection is the main knob this library exposes and the signed families never had the problem, because they name the algorithm in the type. Status: `done` — option 1 of the issue (rename for explicitness, old names kept as `[Obsolete]` aliases until a future major version): `UInt32WangNaiveHasher` and `UInt64Murmur3Hasher` ship, and the aliases forward to them rather than repeating the mixer, so the pairs cannot drift and no hash value moved. Two calls are worth recording. First, `UInt64Hasher` keeps its `IHashProvider64<ulong>` implementation rather than being reduced to the 32-bit surface: dropping it would push an existing sketch back to the 2^32 entropy floor `IHashProvider64<T>` exists to escape, silently, as a side effect of a *naming* change. Second, the identity tier stays signed-only — an unsigned key reaches the zero-work floor with a free cast at the call site, so a `UInt32IdentityHasher` would be a type that adds nothing — and that asymmetry is now pinned by a test rather than left to be rediscovered as a gap. The regression guard is the family-wide `IntegerHasherFamilyNamingTests`, which fails on a new bare-named integer hasher or a width missing a tier; it also pins the one unsigned/signed pair that is deliberately *not* bit-identical, the 32-bit naive fold, whose shift is arithmetic on `int` and logical on `uint`. Tracked in [#297](https://github.com/marius-bughiu/Celerity/issues/297).

The naming test asserted that UInt32IdentityHasher / UInt64IdentityHasher must
not exist, on the premise that an unsigned caller reaches the zero-work floor
with a cast. That premise only holds for a direct Hash call. The collections
take the hasher as a type parameter constrained to IHashProvider<TKey> and
invoke it internally, so a uint-keyed collection cannot be given a signed
identity hasher and the caller has nowhere to put a cast — meaning half the
integer widths have no reachable zero-work tier at all.

Removed the assertion and the matching ROADMAP claim. The test now pins only
the three algorithm-named mixing tiers, which is what this change is about.
The real gap is filed as #357 rather than settled inside a rename.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 01:40
@marius-bughiu

Copy link
Copy Markdown
Owner Author

Round 2 — both findings were in the suppressed block, and both were right.

IntegerHasherFamilyNamingTests.cs:74 / ROADMAP.md:244 — the unsigned identity hasher. Agreed, and this was the more useful catch of the two rounds. Fixed in 7bbc7c3.

The premise I wrote — that an unsigned caller reaches the zero-work floor with new Int32IdentityHasher().Hash((int)u) — only holds for a direct Hash call, which is not how the hashers are consumed. CelerityDictionary.cs:21 constrains THasher : struct, IHashProvider<TKey> and the collection invokes Hash internally, so for TKey = uint an IHashProvider<int> does not satisfy the constraint and there is no call site for the caller to cast in. The consequence is worse than the redundant type I claimed it would be: uint- and ulong-keyed collections have no reachable zero-work tier at all, and the same applies to the sets, the frozen types and the sketches. So the assertion was not merely unnecessary — it pinned a false conclusion and would have blocked the fix.

Removed the whole TheIdentityTier_ShouldRemainSignedOnly_AsADeliberateAsymmetry test (including its positive half, which was not this PR's business either) and rewrote the ROADMAP sentence to record an open gap instead of a decision. The suite now pins only the three algorithm-named mixing tiers.

I did not add the two hashers here. Closing the identity tier is a separate call — two-line types are close to the "yet another hasher variant" shape this project resists, and the argument for them (completing an existing ladder against a documented decision rule, currently unreachable from the collections) deserves triage rather than being smuggled into a rename. Filed as #357 with that tension stated explicitly, and the ROADMAP entry points at it.

Local re-verification: build clean, 1224 hashing tests pass on each of net8.0 / net9.0 / net10.0, doc-anchor check green.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Suppressed comments (2)

ROADMAP.md:244

  • The PR description still states that the unsigned identity gap is deliberate and pinned by a test, and that these aliases remain for only a release. This updated roadmap records the opposite: identity is an open gap tracked by #357, no test pins the asymmetry, and removal is deferred to a future major version. Update the PR's “What ships,” cross-cutting-test, and roadmap text so reviewers are not approving stale design and lifecycle claims.
- The bare `UIntNN Hasher` name meant opposite tiers of the escalation ladder in the two unsigned widths: `UInt32Hasher` was the cheap XOR-fold while `UInt64Hasher` was the strong Murmur3 `fmix64` finalizer, so a caller who benchmarked on `uint` and then moved to `ulong` keys by analogy silently changed hash *strength*, not just key width. Hasher selection is the main knob this library exposes and the signed families never had the problem, because they name the algorithm in the type. Status: `done` — option 1 of the issue (rename for explicitness, old names kept as `[Obsolete]` aliases until a future major version): `UInt32WangNaiveHasher` and `UInt64Murmur3Hasher` ship, and the aliases forward to them rather than repeating the mixer, so the pairs cannot drift and no hash value moved. Two calls are worth recording. First, `UInt64Hasher` keeps its `IHashProvider64<ulong>` implementation rather than being reduced to the 32-bit surface: dropping it would push an existing sketch back to the 2^32 entropy floor `IHashProvider64<T>` exists to escape, silently, as a side effect of a *naming* change. Second, the identity tier is still signed-only, and that is now recorded as an open gap rather than a decision: the first draft argued an unsigned key reaches the zero-work floor with a cast at the call site, which is false for the primary use case — the collections constrain `THasher` to `IHashProvider<TKey>` and invoke `Hash` internally, so no `IHashProvider<uint>` identity hasher means no zero-work floor for a `uint`-keyed collection at all. Filed as [#357](https://github.com/marius-bughiu/Celerity/issues/357) rather than settled inside a naming change. The regression guard is the family-wide `IntegerHasherFamilyNamingTests`, which fails on a new bare-named integer hasher or a width missing a tier; it also pins the one unsigned/signed pair that is deliberately *not* bit-identical, the 32-bit naive fold, whose shift is arithmetic on `int` and logical on `uint`. Tracked in [#297](https://github.com/marius-bughiu/Celerity/issues/297).

docs/api/hashing.md:81

  • This roster omits UInt64Hasher, even though the alias still implements IHashProvider64<ulong> and the contract test intentionally keeps both types. Because the table claims to list hashers with Hash64, it now contradicts the API and the compatibility note at line 766. Keep the alias in the row, marked obsolete.
| `ulong` | `UInt64WangHasher`, `UInt64Murmur3Hasher` | `Hash` is the low 32 bits of `Hash64` |

The "which built-in hashers implement it" table lost UInt64Hasher when the row
was updated to name UInt64Murmur3Hasher. The alias still implements
IHashProvider64<ulong> — deliberately, so a sketch parameterized on it does not
drop to the 2^32 floor mid-migration — and the contract test roster still
carries it, so the table was the one surface saying otherwise.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 01:46
@marius-bughiu

Copy link
Copy Markdown
Owner Author

Round 3 — two suppressed findings again, both correct.

docs/api/hashing.md:81 — the IHashProvider64 roster dropped UInt64Hasher. Agreed, fixed in 2730330. When I updated the ulong row to name UInt64Murmur3Hasher I replaced the alias instead of adding alongside it. The alias still implements IHashProvider64<ulong> on purpose — that is the whole reason a mid-migration sketch does not fall back to the 2^32 floor — and HashProvider64ContractTests.Expected64BitHashers still lists it, so that table was the single surface contradicting both the API and the compatibility note further down the same page. The row now carries it, marked as the obsolete alias.

ROADMAP.md:244 — the PR description was stale. Agreed, and a fair catch: the body still described the identity asymmetry as deliberate and test-pinned, which is what 7bbc7c3 had just removed. Reviewers reading the description would have been approving a design claim the branch no longer makes. Updated the description's "What ships" bullet and the cross-cutting-test paragraph to match, condensed the CHANGELOG paragraph to describe what actually landed, and added a "Review rounds" section so the history of what changed under review is visible without diffing three commits.

I could not find a stale "for one release" claim in the description — that phrase was in the two hashers' XML remarks and in ROADMAP.md, both corrected in 3f3ac5a, and the description has said "future major version" since it was written. Flagging that part as already-satisfied rather than silently ignored.

No source change in this round beyond the one table cell; doc-anchor check green.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Suppressed comments (1)

README.md:675

  • This 64-bit hasher roster is now incomplete: UInt64Hasher still implements IHashProvider64<ulong> for compatibility (and is retained in the exact roster in HashProvider64ContractTests and docs/api/hashing.md), but replacing it here removes it entirely. Keep the obsolete alias listed so the README does not contradict the compatibility contract.
> **Counting past ~10^8 distinct elements? Pick a 64-bit hasher.** The probabilistic sketches (`HyperLogLog`, `BloomFilter`, `CuckooFilter`, `XorFilter`, `CountMinSketch`) never store the element, so two elements that hash alike are indistinguishable forever — and a 32-bit hash reaches only 2^32 ≈ 4.3 billion values, no matter how it is widened. Hashers that carry genuine 64-bit entropy implement **`IHashProvider64<T>`** and the sketches route through it automatically: `Int64WangHasher` / `Int64Murmur3Hasher` (`long`), `UInt64WangHasher` / `UInt64Murmur3Hasher` (`ulong`), `GuidHasher` (`Guid`), and the nine 64-bit `string` hashers (`StringXxHash64Hasher`, `StringXxHash3Hasher`, `StringCityHash64Hasher`, `StringMetroHash64Hasher`, `StringHighwayHash64Hasher`, `StringSipHash13Hasher`, `StringSipHash24Hasher`, `StringFnV1A64Hasher`, `StringFnV164Hasher`). They already computed 64 bits internally and folded them away, so `Hash64` costs nothing extra. With a 32-bit-only hasher the sketches still work — `HyperLogLog` applies the classical large-range correction so its estimate stays honest — but the entropy floor is real. See [`IHashProvider64<T>`](docs/api/hashing.md#ihashprovider64t).

Same omission as the API-reference roster: replacing UInt64Hasher with
UInt64Murmur3Hasher in the sketch-entropy note dropped a type that still
implements IHashProvider64<ulong>. Listed again, marked deprecated, so the
sentence is complete without pointing a new reader at the old name.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 01:51
@marius-bughiu

Copy link
Copy Markdown
Owner Author

Round 4 — one suppressed finding, the same omission as round 3 in a second place. Agreed, fixed in 98a5f13.

README.md:675 had the same edit mistake as the API-reference roster: swapping in UInt64Murmur3Hasher replaced the alias instead of joining it, so a type that still implements IHashProvider64<ulong> vanished from a sentence about which hashers implement IHashProvider64<ulong>.

One deliberate difference from the reference table, worth stating rather than leaving to be inferred. That table is a roster — it is headed "Which built-in hashers implement it" — so the alias belongs in it plainly. The README sentence is guidance: it tells someone counting past 10^8 elements which hasher to reach for. Listing a deprecated type there unqualified would hand a new reader the name we are trying to retire. So it now reads `ulong`, as does the deprecated `UInt64Hasher` alias — prefer the named type: factually complete against the contract, and still unambiguous about which one to pick.

Doc-anchor check green. No source change.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/Celerity.Tests/Hashing/IntegerHasherFamilyNamingTests.cs:12

  • The summary says every unsigned hasher agrees bit-for-bit with its signed peer, but this suite explicitly documents and tests the UInt32WangNaiveHasher exception below. Reword this sentence so the class contract does not contradict its own regression test.
/// mixing tiers, and an unsigned hasher agrees bit-for-bit with its signed peer.

The class summary claimed every unsigned hasher agrees bit-for-bit with its
signed peer, while a test three methods down pins the one pair that does not.
Named the exception in the summary.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 9, 2026 01:55
@marius-bughiu

Copy link
Copy Markdown
Owner Author

Round 5 — one suppressed finding, correct. Fixed in 1a63a55.

IntegerHasherFamilyNamingTests' class summary asserted that an unsigned hasher agrees bit-for-bit with its signed peer, full stop, while TheNaive32BitFold_ShouldDivergeBetweenTheSignedAndUnsignedPeers_OnANegativeKey three methods below pins the pair that does not. The summary now names the exception, so the stated contract and the test agree. Suite passes, 24 cases per TFM.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

@marius-bughiu

Copy link
Copy Markdown
Owner Author

Note on the benchmark comment this run will produce, so three rows do not read as an anomaly.

Renaming the arms means main has no counterpart for UInt32_WangNaive, UInt64_Murmur3 or UInt64_Murmur3_Hash64. I checked scripts/benchmark_comment.js:216-224 rather than guessing: a name absent from the base report renders as 🆕 new and is not counted toward the errored total — that path is reserved for a name present in the base whose statistics are missing (⚠️ base errored). So the three renamed arms should appear as new rows with no delta, and the summary line should not be skewed by them.

The mirror image is that the old UInt32_Default / UInt64_Default / UInt64_Default_Hash64 rows exist only on the base side, and the comment iterates the PR report, so they simply drop out of the table rather than showing as removed. Both effects are one-off and expected from the rename; from the next run on main onward the three arms pair normally again. The CHANGELOG entry says the same thing for the published dashboard, where the old series stops and a new one starts.

Nothing here needs action — flagging it because a reviewer scanning the comment would reasonably wonder why three uint / ulong rows lost their comparison.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

Benchmarks

3 regressions ⚠️ vs main (rows past ±10% and beyond 3σ).

Highlights

Benchmark This PR StdDev main Δ
SortedSpanBenchmark.SortedSpan_Except(ItemCount: 1000) 2.56 μs 16.0 ns 2.12 μs +20.9% ⚠️
StringKeyProbeBenchmark.CeleritySet_Contains(ItemCount: 100000) 5.23 ms 112.21 μs 4.71 ms +11.2% ⚠️
PooledCeleritySetBenchmark.HashSet_Remove(ItemCount: 1000) 35.08 μs 1.48 μs 26.14 μs +34.2% ⚠️
Collections (646)
Benchmark This PR StdDev main Δ
FrozenCeleritySetBenchmark.FrozenSet_Build(ItemCount: 1000) 173.34 μs 496.2 ns 174.47 μs -0.6%
FrozenCeleritySetBenchmark.FrozenCeleritySet_Build(ItemCount: 1000) 2.55 ms 67.08 μs 2.56 ms -0.6%
FrozenCeleritySetBenchmark.FrozenSet_Build(ItemCount: 100000) 29.86 ms 385.40 μs 30.92 ms -3.5%
FrozenCeleritySetBenchmark.FrozenCeleritySet_Build(ItemCount: 100000) 1.56 s 72.74 ms 1.66 s -6.5%
FrozenCeleritySetBenchmark.FrozenSet_Contains(ItemCount: 1000) 7.10 μs 10.9 ns 7.16 μs -0.8%
FrozenCeleritySetBenchmark.FrozenCeleritySet_Contains(ItemCount: 1000) 79.58 μs 215.4 ns 79.37 μs +0.3%
FrozenCeleritySetBenchmark.FrozenSet_Contains(ItemCount: 100000) 1.85 ms 17.54 μs 1.88 ms -1.4%
FrozenCeleritySetBenchmark.FrozenCeleritySet_Contains(ItemCount: 100000) 8.33 ms 159.73 μs 8.48 ms -1.8%
FenwickTreeBenchmark.Array_Mixed(ItemCount: 1000) 202.70 μs 559.2 ns 203.04 μs -0.2%
FenwickTreeBenchmark.FenwickTree_Mixed(ItemCount: 1000) 11.08 μs 52.3 ns 11.37 μs -2.5%
FenwickTreeBenchmark.Array_Mixed(ItemCount: 100000) 184.39 ms 604.75 μs 184.40 ms -0.0%
FenwickTreeBenchmark.FenwickTree_Mixed(ItemCount: 100000) 633.95 μs 14.32 μs 639.92 μs -0.9%
FenwickTreeBenchmark.Array_RangeSum(ItemCount: 1000) 249.22 μs 421.0 ns 249.00 μs +0.1%
FenwickTreeBenchmark.FenwickTree_RangeSum(ItemCount: 1000) 6.85 μs 5.9 ns 6.85 μs -0.0%
FenwickTreeBenchmark.Array_RangeSum(ItemCount: 100000) 223.61 ms 25.43 ms 178.82 ms +25.0%
FenwickTreeBenchmark.FenwickTree_RangeSum(ItemCount: 100000) 216.87 μs 9.22 μs 217.37 μs -0.2%
CeleritySetBenchmark.HashSet_Add(ItemCount: 1000) 14.16 μs 456.5 ns 14.47 μs -2.1%
CountMinSketchBenchmark.Dictionary_Add(ItemCount: 1000) 10.70 μs 47.1 ns 10.65 μs +0.5%
CeleritySetBenchmark.CeleritySet_Add(ItemCount: 1000) 9.69 μs 133.2 ns 9.39 μs +3.2%
CountMinSketchBenchmark.CountMinSketch_Add(ItemCount: 1000) 11.25 μs 84.8 ns 11.05 μs +1.8%
CeleritySetBenchmark.HashSet_Add(ItemCount: 100000) 5.14 ms 111.10 μs 5.14 ms -0.1%
CountMinSketchBenchmark.Dictionary_Add(ItemCount: 100000) 1.54 ms 43.64 μs 1.49 ms +3.6%
CeleritySetBenchmark.CeleritySet_Add(ItemCount: 100000) 3.32 ms 68.45 μs 3.52 ms -5.7%
CountMinSketchBenchmark.CountMinSketch_Add(ItemCount: 100000) 951.40 μs 15.81 μs 963.26 μs -1.2%
BitSetBenchmark.BitArray_And(ItemCount: 1024) 56.7 ns 1.2 ns 58.0 ns -2.3%
BitSetBenchmark.BitSet_And(ItemCount: 1024) 1.57 μs 344.7 ns 1.25 μs +26.1%
BitSetBenchmark.BitArray_And(ItemCount: 1000000) 44.70 μs 732.9 ns 44.87 μs -0.4%
BitSetBenchmark.BitSet_And(ItemCount: 1000000) 4.48 ms 5.64 μs 4.48 ms -0.0%
CeleritySetBenchmark.HashSet_Contains(ItemCount: 1000) 4.80 μs 42.9 ns 4.75 μs +1.1%
CeleritySetBenchmark.CeleritySet_Contains(ItemCount: 1000) 1.85 μs 6.4 ns 1.85 μs -0.1%
CeleritySetBenchmark.HashSet_Contains(ItemCount: 100000) 1.61 ms 14.19 μs 1.65 ms -2.5%
CeleritySetBenchmark.CeleritySet_Contains(ItemCount: 100000) 600.98 μs 2.89 μs 605.50 μs -0.7%
CountMinSketchBenchmark.Dictionary_Estimate(ItemCount: 1000) 4.39 μs 14.8 ns 4.37 μs +0.3%
CountMinSketchBenchmark.CountMinSketch_Estimate(ItemCount: 1000) 10.07 μs 16.3 ns 10.06 μs +0.1%
CountMinSketchBenchmark.Dictionary_Estimate(ItemCount: 100000) 489.37 μs 1.34 μs 567.04 μs -13.7%
CountMinSketchBenchmark.CountMinSketch_Estimate(ItemCount: 100000) 1.97 ms 3.13 μs 1.96 ms +0.2%
LruCacheBenchmark.Dictionary_Get(ItemCount: 1000) 26.29 μs 1.07 μs 24.98 μs +5.2%
LruCacheBenchmark.LruCache_Get(ItemCount: 1000) 6.94 μs 145.8 ns 7.25 μs -4.2%
LruCacheBenchmark.Dictionary_Get(ItemCount: 100000) 26.62 μs 1.24 μs 25.98 μs +2.5%
LruCacheBenchmark.LruCache_Get(ItemCount: 100000) 6.91 μs 55.4 ns 7.19 μs -3.8%
LruCacheBenchmark.Dictionary_GetMissing(ItemCount: 1000) 4.81 μs 74.5 ns 4.83 μs -0.6%
LruCacheBenchmark.LruCache_GetMissing(ItemCount: 1000) 3.60 μs 5.8 ns 3.60 μs -0.1%
LruCacheBenchmark.Dictionary_GetMissing(ItemCount: 100000) 541.49 μs 23.29 μs 518.99 μs +4.3%
LruCacheBenchmark.LruCache_GetMissing(ItemCount: 100000) 1.34 ms 1.00 μs 1.34 ms +0.1%
PooledCelerityDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 14.67 μs 851.0 ns 13.52 μs +8.4%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Insert(ItemCount: 1000) 8.09 μs 51.9 ns 8.44 μs -4.1%
PooledCelerityDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 5.03 ms 69.04 μs 5.16 ms -2.5%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Insert(ItemCount: 100000) 2.99 ms 21.50 μs 3.06 ms -2.4%
PooledCelerityDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.70 μs 31.8 ns 4.71 μs -0.2%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Lookup(ItemCount: 1000) 2.35 μs 10.2 ns 2.43 μs -3.5%
PooledCelerityDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.63 ms 21.16 μs 1.64 ms -0.6%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Lookup(ItemCount: 100000) 709.43 μs 6.71 μs 752.57 μs -5.7%
BitSetBenchmark.BitArray_Or(ItemCount: 1024) 55.0 ns 0.7 ns 56.7 ns -2.9%
BitSetBenchmark.BitSet_Or(ItemCount: 1024) 1.25 μs 5.4 ns 1.24 μs +0.1%
BitSetBenchmark.BitArray_Or(ItemCount: 1000000) 44.41 μs 476.3 ns 44.69 μs -0.6%
BitSetBenchmark.BitSet_Or(ItemCount: 1000000) 4.48 ms 5.04 μs 4.48 ms +0.1%
BitSetBenchmark.BitArray_PopCount(ItemCount: 1024) 1.25 μs 3.1 ns 1.24 μs +0.1%
BitSetBenchmark.BitSet_PopCount(ItemCount: 1024) 7.0 ns 0.0 ns 7.1 ns -0.4%
BitSetBenchmark.BitArray_PopCount(ItemCount: 1000000) 4.83 ms 4.94 μs 4.82 ms +0.1%
BitSetBenchmark.BitSet_PopCount(ItemCount: 1000000) 4.94 μs 3.6 ns 4.94 μs -0.0%
LruCacheBenchmark.Dictionary_Put(ItemCount: 1000) 106.16 μs 5.59 μs 108.29 μs -2.0%
LruCacheBenchmark.LruCache_Put(ItemCount: 1000) 474.39 μs 21.56 μs 475.29 μs -0.2%
LruCacheBenchmark.Dictionary_Put(ItemCount: 100000) 8.37 ms 74.44 μs 7.27 ms +15.1%
LruCacheBenchmark.LruCache_Put(ItemCount: 100000) 5.79 ms 17.08 μs 5.77 ms +0.2%
CeleritySetBenchmark.HashSet_Remove(ItemCount: 1000) 28.80 μs 2.60 μs 30.77 μs -6.4%
PooledCelerityDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 83.30 μs 5.87 μs 85.94 μs -3.1%
CeleritySetBenchmark.CeleritySet_Remove(ItemCount: 1000) 114.58 μs 7.56 μs 130.79 μs -12.4%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Remove(ItemCount: 1000) 119.26 μs 7.26 μs 128.13 μs -6.9%
CeleritySetBenchmark.HashSet_Remove(ItemCount: 100000) 1.89 ms 127.22 μs 1.93 ms -1.9%
PooledCelerityDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.09 ms 38.63 μs 2.09 ms -0.0%
CeleritySetBenchmark.CeleritySet_Remove(ItemCount: 100000) 1.54 ms 172.04 μs 1.61 ms -4.5%
PooledCelerityDictionaryBenchmark.PooledCelerityDictionary_Remove(ItemCount: 100000) 1.63 ms 60.38 μs 2.01 ms -18.8%
PartialSortBenchmark.Array_Select(ItemCount: 100) 475.8 ns 11.4 ns 477.7 ns -0.4%
PartialSortBenchmark.PartialSort_Select(ItemCount: 100) 379.2 ns 28.0 ns 339.5 ns +11.7%
PartialSortBenchmark.Array_Select(ItemCount: 1000) 9.98 μs 50.8 ns 10.00 μs -0.1%
PartialSortBenchmark.PartialSort_Select(ItemCount: 1000) 5.57 μs 14.1 ns 5.57 μs +0.1%
PartialSortBenchmark.Array_Select(ItemCount: 100000) 5.78 ms 175.09 μs 5.85 ms -1.3%
PartialSortBenchmark.PartialSort_Select(ItemCount: 100000) 1.02 ms 21.19 μs 1.04 ms -2.1%
PartialSortBenchmark.Array_Select(ItemCount: 1000000) 65.78 ms 67.04 μs 65.81 ms -0.0%
PartialSortBenchmark.PartialSort_Select(ItemCount: 1000000) 8.67 ms 1.03 ms 7.66 ms +13.2%
PartialSortBenchmark.Array_SortPrefix(ItemCount: 100) 469.0 ns 6.2 ns 472.6 ns -0.8%
PartialSortBenchmark.PartialSort_SortPrefix(ItemCount: 100) 394.9 ns 43.2 ns 334.7 ns +18.0%
PartialSortBenchmark.Array_SortPrefix(ItemCount: 1000) 9.21 μs 684.8 ns 10.00 μs -8.0%
PartialSortBenchmark.PartialSort_SortPrefix(ItemCount: 1000) 5.34 μs 543.5 ns 5.81 μs -8.0%
PartialSortBenchmark.Array_SortPrefix(ItemCount: 100000) 5.86 ms 28.32 μs 5.69 ms +3.0%
PartialSortBenchmark.PartialSort_SortPrefix(ItemCount: 100000) 1.10 ms 45.72 μs 1.13 ms -2.6%
PartialSortBenchmark.Array_SortPrefix(ItemCount: 1000000) 65.86 ms 157.29 μs 67.51 ms -2.4%
PartialSortBenchmark.PartialSort_SortPrefix(ItemCount: 1000000) 8.69 ms 76.41 μs 9.16 ms -5.1%
PartialSortBenchmark.Array_TopK(ItemCount: 100) 476.6 ns 3.5 ns 516.9 ns -7.8%
PartialSortBenchmark.PartialSort_TopK(ItemCount: 100) 75.9 ns 0.1 ns 76.3 ns -0.6%
PartialSortBenchmark.Array_TopK(ItemCount: 1000) 8.15 μs 93.3 ns 8.54 μs -4.6%
PartialSortBenchmark.PartialSort_TopK(ItemCount: 1000) 1.38 μs 5.4 ns 1.38 μs -0.1%
PartialSortBenchmark.Array_TopK(ItemCount: 100000) 2.05 ms 171.06 μs 1.93 ms +5.9%
PartialSortBenchmark.PartialSort_TopK(ItemCount: 100000) 413.43 μs 1.52 μs 410.13 μs +0.8%
PartialSortBenchmark.Array_TopK(ItemCount: 1000000) 20.83 ms 338.95 μs 20.52 ms +1.5%
PartialSortBenchmark.PartialSort_TopK(ItemCount: 1000000) 5.25 ms 217.06 μs 5.24 ms +0.1%
PartialSortBenchmark.Array_TopKHeap(ItemCount: 100) 172.4 ns 2.0 ns 173.4 ns -0.5%
PartialSortBenchmark.PartialSort_TopKHeap(ItemCount: 100) 75.7 ns 0.2 ns 75.6 ns +0.0%
PartialSortBenchmark.Array_TopKHeap(ItemCount: 1000) 2.37 μs 6.5 ns 2.36 μs +0.5%
PartialSortBenchmark.PartialSort_TopKHeap(ItemCount: 1000) 1.38 μs 4.1 ns 1.38 μs -0.0%
PartialSortBenchmark.Array_TopKHeap(ItemCount: 100000) 542.99 μs 1.84 μs 543.05 μs -0.0%
PartialSortBenchmark.PartialSort_TopKHeap(ItemCount: 100000) 413.58 μs 1.39 μs 401.16 μs +3.1%
PartialSortBenchmark.Array_TopKHeap(ItemCount: 1000000) 6.69 ms 44.64 μs 6.86 ms -2.4%
PartialSortBenchmark.PartialSort_TopKHeap(ItemCount: 1000000) 5.26 ms 167.92 μs 5.46 ms -3.5%
BitSetBenchmark.BitArray_Xor(ItemCount: 1024) 59.5 ns 2.0 ns 56.8 ns +4.7%
BitSetBenchmark.BitSet_Xor(ItemCount: 1024) 1.25 μs 4.8 ns 1.25 μs -0.2%
BitSetBenchmark.BitArray_Xor(ItemCount: 1000000) 44.41 μs 289.0 ns 44.49 μs -0.2%
BitSetBenchmark.BitSet_Xor(ItemCount: 1000000) 4.47 ms 3.54 μs 4.48 ms -0.0%
EnumSetBenchmark.HashSet_Add 550.1 ns 2.8 ns 554.1 ns -0.7%
EnumSetBenchmark.EnumSet_Add 84.0 ns 0.4 ns 230.2 ns -63.5%
BloomFilterBenchmark.HashSet_Add(ItemCount: 1000) 12.27 μs 273.2 ns 11.91 μs +3.0%
SparseSetBenchmark.HashSet_Add(ItemCount: 1000) 6.40 μs 184.1 ns 6.95 μs -7.9%
BloomFilterBenchmark.BloomFilter_Add(ItemCount: 1000) 14.46 μs 19.1 ns 14.44 μs +0.1%
SparseSetBenchmark.SparseSet_Add(ItemCount: 1000) 5.91 μs 30.7 ns 5.93 μs -0.3%
BloomFilterBenchmark.HashSet_Add(ItemCount: 100000) 4.64 ms 170.55 μs 4.46 ms +4.0%
SparseSetBenchmark.HashSet_Add(ItemCount: 100000) 1.70 ms 36.89 μs 1.74 ms -2.0%
BloomFilterBenchmark.BloomFilter_Add(ItemCount: 100000) 1.09 ms 4.40 μs 1.09 ms +0.0%
SparseSetBenchmark.SparseSet_Add(ItemCount: 100000) 1.35 ms 29.81 μs 1.44 ms -5.7%
SparseSetBenchmark.HashSet_ClearRefill(ItemCount: 1000) 6.16 μs 208.2 ns 5.98 μs +2.9%
SparseSetBenchmark.SparseSet_ClearRefill(ItemCount: 1000) 4.67 μs 125.2 ns 4.60 μs +1.5%
SparseSetBenchmark.HashSet_ClearRefill(ItemCount: 100000) 1.36 ms 4.96 μs 1.36 ms -0.4%
SparseSetBenchmark.SparseSet_ClearRefill(ItemCount: 100000) 639.67 μs 742.1 ns 639.70 μs -0.0%
EnumSetBenchmark.HashSet_Contains 175.2 ns 0.1 ns 175.0 ns +0.1%
EnumSetBenchmark.EnumSet_Contains 45.8 ns 0.1 ns 46.0 ns -0.3%
BloomFilterBenchmark.HashSet_Contains(ItemCount: 1000) 4.70 μs 18.8 ns 4.77 μs -1.3%
SparseSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.65 μs 4.0 ns 4.65 μs -0.1%
BloomFilterBenchmark.BloomFilter_Contains(ItemCount: 1000) 12.51 μs 4.5 ns 12.51 μs -0.1%
SparseSetBenchmark.SparseSet_Contains(ItemCount: 1000) 1.29 μs 1.3 ns 1.36 μs -5.7%
BloomFilterBenchmark.HashSet_Contains(ItemCount: 100000) 1.55 ms 2.14 μs 1.57 ms -0.8%
SparseSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.36 ms 842.0 ns 1.35 ms +0.8%
BloomFilterBenchmark.BloomFilter_Contains(ItemCount: 100000) 868.42 μs 521.5 ns 868.07 μs +0.0%
SparseSetBenchmark.SparseSet_Contains(ItemCount: 100000) 254.41 μs 759.8 ns 253.75 μs +0.3%
BloomFilterBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.54 μs 5.2 ns 4.54 μs +0.1%
BloomFilterBenchmark.BloomFilter_ContainsMissing(ItemCount: 1000) 3.53 μs 13.1 ns 3.52 μs +0.2%
BloomFilterBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.94 ms 7.16 μs 1.92 ms +1.1%
BloomFilterBenchmark.BloomFilter_ContainsMissing(ItemCount: 100000) 1.49 ms 664.2 ns 1.49 ms -0.0%
CelerityMultiSetBenchmark.Dictionary_Count(ItemCount: 1000) 10.21 μs 89.9 ns 10.34 μs -1.2%
CelerityMultiSetBenchmark.CelerityMultiSet_Count(ItemCount: 1000) 5.18 μs 15.1 ns 5.18 μs -0.1%
CelerityMultiSetBenchmark.Dictionary_Count(ItemCount: 100000) 1.45 ms 9.34 μs 1.44 ms +0.9%
CelerityMultiSetBenchmark.CelerityMultiSet_Count(ItemCount: 100000) 726.63 μs 4.16 μs 732.14 μs -0.8%
SortedSpanBenchmark.HashSet_Except(ItemCount: 1000) 12.90 μs 59.6 ns 12.59 μs +2.4%
SortedSpanBenchmark.Linq_ExceptLinq(ItemCount: 1000) 20.32 μs 220.1 ns 19.87 μs +2.3%
SortedSpanBenchmark.SortedSpan_Except(ItemCount: 1000) 2.56 μs 16.0 ns 2.12 μs +20.9% ⚠️
SortedSpanBenchmark.HashSet_Except(ItemCount: 100000) 2.47 ms 52.00 μs 2.41 ms +2.2%
SortedSpanBenchmark.Linq_ExceptLinq(ItemCount: 100000) 3.52 ms 68.14 μs 3.53 ms -0.2%
SortedSpanBenchmark.SortedSpan_Except(ItemCount: 100000) 878.00 μs 5.08 μs 874.32 μs +0.4%
SwissDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 12.94 μs 98.3 ns 13.63 μs -5.1%
SwissDictionaryBenchmark.SwissDictionary_Insert(ItemCount: 1000) 28.93 μs 126.0 ns 28.91 μs +0.1%
SwissDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 4.56 ms 185.49 μs 4.57 ms -0.2%
SwissDictionaryBenchmark.SwissDictionary_Insert(ItemCount: 100000) 3.89 ms 14.83 μs 3.93 ms -0.9%
SortedSpanBenchmark.HashSet_Intersect(ItemCount: 1000) 19.16 μs 29.6 ns 19.24 μs -0.4%
SortedSpanBenchmark.Linq_IntersectLinq(ItemCount: 1000) 14.52 μs 55.1 ns 14.48 μs +0.3%
SortedSpanBenchmark.SortedSpan_Intersect(ItemCount: 1000) 2.67 μs 6.6 ns 2.68 μs -0.1%
SortedSpanBenchmark.HashSet_Intersect(ItemCount: 100000) 3.74 ms 29.63 μs 3.80 ms -1.7%
SortedSpanBenchmark.Linq_IntersectLinq(ItemCount: 100000) 2.72 ms 16.88 μs 2.71 ms +0.3%
SortedSpanBenchmark.SortedSpan_Intersect(ItemCount: 100000) 857.54 μs 1.32 μs 857.30 μs +0.0%
SortedSpanBenchmark.HashSet_IntersectAsymmetric(ItemCount: 1000) 7.56 μs 6.7 ns 7.58 μs -0.3%
SortedSpanBenchmark.SortedSpan_IntersectAsymmetric(ItemCount: 1000) 97.7 ns 0.3 ns 97.7 ns +0.0%
SortedSpanBenchmark.HashSet_IntersectAsymmetric(ItemCount: 100000) 1.58 ms 9.51 μs 1.58 ms +0.0%
SortedSpanBenchmark.SortedSpan_IntersectAsymmetric(ItemCount: 100000) 13.07 μs 679.7 ns 13.06 μs +0.0%
SortedSpanBenchmark.HashSet_IntersectCount(ItemCount: 1000) 12.03 μs 83.1 ns 11.94 μs +0.7%
SortedSpanBenchmark.SortedSpan_IntersectCount(ItemCount: 1000) 2.08 μs 2.3 ns 2.08 μs -0.2%
SortedSpanBenchmark.HashSet_IntersectCount(ItemCount: 100000) 2.49 ms 91.93 μs 2.41 ms +3.5%
SortedSpanBenchmark.SortedSpan_IntersectCount(ItemCount: 100000) 840.35 μs 889.5 ns 840.28 μs +0.0%
CelerityMultiSetBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.38 μs 9.2 ns 4.53 μs -3.4%
SwissDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.90 μs 155.1 ns 4.75 μs +3.1%
CelerityMultiSetBenchmark.CelerityMultiSet_Lookup(ItemCount: 1000) 1.72 μs 1.1 ns 1.72 μs -0.2%
SwissDictionaryBenchmark.SwissDictionary_Lookup(ItemCount: 1000) 3.20 μs 140.6 ns 3.02 μs +6.0%
CelerityMultiSetBenchmark.Dictionary_Lookup(ItemCount: 100000) 634.03 μs 12.56 μs 625.98 μs +1.3%
SwissDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.60 ms 6.85 μs 1.58 ms +0.9%
CelerityMultiSetBenchmark.CelerityMultiSet_Lookup(ItemCount: 100000) 189.60 μs 284.0 ns 189.39 μs +0.1%
SwissDictionaryBenchmark.SwissDictionary_Lookup(ItemCount: 100000) 804.00 μs 10.91 μs 803.62 μs +0.0%
SegmentTreeBenchmark.Array_Mixed(ItemCount: 1000) 193.72 μs 12.09 μs 185.98 μs +4.2%
SegmentTreeBenchmark.SegmentTree_Mixed(ItemCount: 1000) 38.63 μs 202.5 ns 38.83 μs -0.5%
SegmentTreeBenchmark.Array_Mixed(ItemCount: 100000) 21.30 ms 52.65 μs 21.23 ms +0.3%
SegmentTreeBenchmark.SegmentTree_Mixed(ItemCount: 100000) 1.21 ms 15.10 μs 1.21 ms +0.5%
SortedSpanBenchmark.HashSet_Overlaps(ItemCount: 1000) 7.87 μs 30.0 ns 7.90 μs -0.3%
SortedSpanBenchmark.SortedSpan_Overlaps(ItemCount: 1000) 8.2 ns 0.0 ns 8.2 ns -0.0%
SortedSpanBenchmark.HashSet_Overlaps(ItemCount: 100000) 1.21 ms 23.05 μs 1.20 ms +0.9%
SortedSpanBenchmark.SortedSpan_Overlaps(ItemCount: 100000) 4.4 ns 0.1 ns 4.4 ns -0.4%
SegmentTreeBenchmark.Array_RangeMin(ItemCount: 1000) 241.54 μs 162.2 ns 241.48 μs +0.0%
SegmentTreeBenchmark.SegmentTree_RangeMin(ItemCount: 1000) 20.82 μs 24.1 ns 20.82 μs -0.0%
SegmentTreeBenchmark.Array_RangeMin(ItemCount: 100000) 40.76 ms 54.63 μs 40.71 ms +0.1%
SegmentTreeBenchmark.SegmentTree_RangeMin(ItemCount: 100000) 266.68 μs 1.01 μs 266.57 μs +0.0%
EnumSetBenchmark.HashSet_Remove 3.00 μs 86.3 ns 3.66 μs -18.1%
EnumSetBenchmark.EnumSet_Remove 1.22 μs 192.7 ns 1.45 μs -16.0%
CelerityMultiSetBenchmark.Dictionary_Remove(ItemCount: 1000) 51.65 μs 7.15 μs 54.01 μs -4.4%
SwissDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 80.74 μs 7.36 μs 82.07 μs -1.6%
CelerityMultiSetBenchmark.CelerityMultiSet_Remove(ItemCount: 1000) 87.95 μs 8.04 μs 79.84 μs +10.2%
SwissDictionaryBenchmark.SwissDictionary_Remove(ItemCount: 1000) 73.16 μs 2.77 μs 76.16 μs -3.9%
SparseSetBenchmark.HashSet_Remove(ItemCount: 1000) 25.01 μs 1.34 μs 26.38 μs -5.2%
SparseSetBenchmark.SparseSet_Remove(ItemCount: 1000) 26.70 μs 3.93 μs 27.69 μs -3.6%
CelerityMultiSetBenchmark.Dictionary_Remove(ItemCount: 100000) 543.72 μs 19.43 μs 545.01 μs -0.2%
SwissDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.05 ms 18.46 μs 2.04 ms +0.6%
CelerityMultiSetBenchmark.CelerityMultiSet_Remove(ItemCount: 100000) 1.26 ms 13.60 μs 1.27 ms -0.3%
SwissDictionaryBenchmark.SwissDictionary_Remove(ItemCount: 100000) 1.62 ms 48.96 μs 1.63 ms -0.5%
SparseSetBenchmark.HashSet_Remove(ItemCount: 100000) 1.49 ms 17.53 μs 1.49 ms +0.4%
SparseSetBenchmark.SparseSet_Remove(ItemCount: 100000) 787.72 μs 13.82 μs 785.85 μs +0.2%
EnumSetBenchmark.HashSet_Union 407.4 ns 9.3 ns 406.9 ns +0.1%
EnumSetBenchmark.EnumSet_Union 21.5 ns 0.3 ns 21.2 ns +1.7%
SortedSpanBenchmark.HashSet_Union(ItemCount: 1000) 17.51 μs 85.7 ns 17.48 μs +0.2%
SortedSpanBenchmark.Linq_UnionLinq(ItemCount: 1000) 19.53 μs 112.8 ns 19.30 μs +1.2%
SortedSpanBenchmark.SortedSpan_Union(ItemCount: 1000) 2.74 μs 103.3 ns 2.83 μs -3.4%
SortedSpanBenchmark.HashSet_Union(ItemCount: 100000) 3.24 ms 43.01 μs 3.27 ms -0.8%
SortedSpanBenchmark.Linq_UnionLinq(ItemCount: 100000) 5.48 ms 531.02 μs 5.48 ms +0.1%
SortedSpanBenchmark.SortedSpan_Union(ItemCount: 100000) 923.55 μs 1.15 μs 922.76 μs +0.1%
CuckooFilterBenchmark.HashSet_Add(ItemCount: 1000) 12.60 μs 243.2 ns 13.73 μs -8.3%
HyperLogLogBenchmark.HashSet_Add(ItemCount: 1000) 12.57 μs 51.8 ns 13.68 μs -8.1%
CuckooFilterBenchmark.CuckooFilter_Add(ItemCount: 1000) 7.95 μs 19.8 ns 7.97 μs -0.3%
HyperLogLogBenchmark.HyperLogLog_Add(ItemCount: 1000) 30.00 μs 79.0 ns 30.15 μs -0.5%
CuckooFilterBenchmark.HashSet_Add(ItemCount: 100000) 4.91 ms 119.85 μs 4.88 ms +0.6%
HyperLogLogBenchmark.HashSet_Add(ItemCount: 100000) 5.06 ms 65.40 μs 5.09 ms -0.6%
CuckooFilterBenchmark.CuckooFilter_Add(ItemCount: 100000) 2.34 ms 2.40 μs 2.34 ms +0.0%
HyperLogLogBenchmark.HyperLogLog_Add(ItemCount: 100000) 492.66 μs 31.56 μs 488.62 μs +0.8%
XorFilterBenchmark.HashSet_Build(ItemCount: 1000) 8.27 μs 36.1 ns 8.24 μs +0.3%
XorFilterBenchmark.XorFilter_Build(ItemCount: 1000) 41.70 μs 328.1 ns 41.39 μs +0.7%
XorFilterBenchmark.HashSet_Build(ItemCount: 100000) 2.08 ms 27.37 μs 2.08 ms -0.1%
XorFilterBenchmark.XorFilter_Build(ItemCount: 100000) 13.42 ms 177.94 μs 13.44 ms -0.2%
CuckooFilterBenchmark.HashSet_Contains(ItemCount: 1000) 4.74 μs 10.2 ns 4.74 μs +0.1%
XorFilterBenchmark.HashSet_Contains(ItemCount: 1000) 4.74 μs 4.9 ns 4.76 μs -0.4%
CuckooFilterBenchmark.CuckooFilter_Contains(ItemCount: 1000) 5.56 μs 6.0 ns 5.55 μs +0.1%
XorFilterBenchmark.XorFilter_Contains(ItemCount: 1000) 7.55 μs 12.5 ns 7.56 μs -0.0%
CuckooFilterBenchmark.HashSet_Contains(ItemCount: 100000) 1.52 ms 2.69 μs 1.52 ms +0.0%
XorFilterBenchmark.HashSet_Contains(ItemCount: 100000) 1.52 ms 4.18 μs 1.52 ms +0.5%
CuckooFilterBenchmark.CuckooFilter_Contains(ItemCount: 100000) 1.97 ms 1.46 μs 1.97 ms +0.0%
XorFilterBenchmark.XorFilter_Contains(ItemCount: 100000) 801.06 μs 336.9 ns 801.31 μs -0.0%
CuckooFilterBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.70 μs 133.4 ns 4.57 μs +3.0%
XorFilterBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.57 μs 6.9 ns 4.57 μs +0.0%
CuckooFilterBenchmark.CuckooFilter_ContainsMissing(ItemCount: 1000) 9.61 μs 5.9 ns 9.61 μs +0.0%
XorFilterBenchmark.XorFilter_ContainsMissing(ItemCount: 1000) 7.55 μs 5.3 ns 7.56 μs -0.2%
CuckooFilterBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.97 ms 3.86 μs 1.98 ms -0.2%
XorFilterBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.91 ms 68.53 μs 1.97 ms -3.0%
CuckooFilterBenchmark.CuckooFilter_ContainsMissing(ItemCount: 100000) 984.79 μs 544.8 ns 985.10 μs -0.0%
XorFilterBenchmark.XorFilter_ContainsMissing(ItemCount: 100000) 804.80 μs 351.5 ns 804.38 μs +0.1%
HyperLogLogBenchmark.HashSet_Estimate(ItemCount: 1000) 0.0 ns 0.0 ns 0.0 ns -64.3%
HyperLogLogBenchmark.HyperLogLog_Estimate(ItemCount: 1000) 26.52 μs 165.3 ns 26.59 μs -0.3%
HyperLogLogBenchmark.HashSet_Estimate(ItemCount: 100000) 0.0 ns 0.0 ns 0.0 ns +44.2%
HyperLogLogBenchmark.HyperLogLog_Estimate(ItemCount: 100000) 27.77 μs 154.6 ns 27.68 μs +0.3%
SmallDictionaryBenchmark.Dictionary_Insert(ItemCount: 8) 169.3 ns 1.8 ns 176.2 ns -3.9%
SmallDictionaryBenchmark.SmallDictionary_Insert(ItemCount: 8) 75.1 ns 0.7 ns 75.5 ns -0.4%
SmallDictionaryBenchmark.Dictionary_Insert(ItemCount: 64) 802.3 ns 5.5 ns 790.8 ns +1.5%
SmallDictionaryBenchmark.SmallDictionary_Insert(ItemCount: 64) 1.04 μs 7.0 ns 1.04 μs +0.0%
HashCachingDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 13.23 μs 214.2 ns 13.18 μs +0.4%
HashCachingDictionaryBenchmark.HashCachingDictionary_Insert(ItemCount: 1000) 10.31 μs 56.7 ns 10.28 μs +0.3%
HashCachingDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 5.04 ms 79.21 μs 5.08 ms -0.7%
HashCachingDictionaryBenchmark.HashCachingDictionary_Insert(ItemCount: 100000) 6.96 ms 210.56 μs 6.94 ms +0.2%
SmallDictionaryBenchmark.Dictionary_Lookup(ItemCount: 8) 38.8 ns 0.3 ns 39.5 ns -1.8%
SmallDictionaryBenchmark.SmallDictionary_Lookup(ItemCount: 8) 23.1 ns 0.3 ns 23.7 ns -2.3%
SmallDictionaryBenchmark.Dictionary_Lookup(ItemCount: 64) 310.2 ns 1.8 ns 303.2 ns +2.3%
SmallDictionaryBenchmark.SmallDictionary_Lookup(ItemCount: 64) 971.9 ns 10.8 ns 973.3 ns -0.1%
HashCachingDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.84 μs 5.6 ns 4.75 μs +1.9%
HashCachingDictionaryBenchmark.HashCachingDictionary_Lookup(ItemCount: 1000) 2.88 μs 55.8 ns 2.86 μs +0.8%
HashCachingDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.65 ms 47.40 μs 1.61 ms +2.9%
HashCachingDictionaryBenchmark.HashCachingDictionary_Lookup(ItemCount: 100000) 868.85 μs 2.37 μs 874.85 μs -0.7%
SmallDictionaryBenchmark.Dictionary_Remove(ItemCount: 8) 1.33 μs 217.5 ns 1.33 μs +0.2%
SmallDictionaryBenchmark.SmallDictionary_Remove(ItemCount: 8) 1.10 μs 74.1 ns 1.24 μs -11.0%
SmallDictionaryBenchmark.Dictionary_Remove(ItemCount: 64) 5.14 μs 532.7 ns 4.63 μs +10.8%
SmallDictionaryBenchmark.SmallDictionary_Remove(ItemCount: 64) 27.90 μs 2.70 μs 21.24 μs +31.3%
HashCachingDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 78.37 μs 8.49 μs 75.99 μs +3.1%
HashCachingDictionaryBenchmark.HashCachingDictionary_Remove(ItemCount: 1000) 112.79 μs 8.63 μs 114.24 μs -1.3%
CuckooFilterBenchmark.HashSet_Remove(ItemCount: 1000) 13.55 μs 25.8 ns 13.57 μs -0.2%
CuckooFilterBenchmark.CuckooFilter_Remove(ItemCount: 1000) 14.24 μs 17.9 ns 14.36 μs -0.9%
HashCachingDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.01 ms 19.31 μs 2.00 ms +0.3%
HashCachingDictionaryBenchmark.HashCachingDictionary_Remove(ItemCount: 100000) 1.89 ms 29.36 μs 1.96 ms -3.9%
CuckooFilterBenchmark.HashSet_Remove(ItemCount: 100000) 3.76 ms 22.18 μs 3.78 ms -0.5%
CuckooFilterBenchmark.CuckooFilter_Remove(ItemCount: 100000) 4.49 ms 10.41 μs 4.60 ms -2.4%
CompressedIntSetBenchmark.HashSet_Add(ItemCount: 1000) 11.91 μs 72.6 ns 11.92 μs -0.1%
HashCachingSetBenchmark.HashSet_Add(ItemCount: 1000) 12.01 μs 197.2 ns 11.87 μs +1.2%
LongSetBenchmark.HashSet_Add(ItemCount: 1000) 12.87 μs 198.6 ns 13.10 μs -1.8%
CompressedIntSetBenchmark.CompressedIntSet_Add(ItemCount: 1000) 33.45 μs 563.3 ns 33.31 μs +0.4%
HashCachingSetBenchmark.HashCachingSet_Add(ItemCount: 1000) 11.43 μs 292.4 ns 10.68 μs +7.1%
LongSetBenchmark.LongSet_Add(ItemCount: 1000) 9.16 μs 123.2 ns 9.08 μs +0.9%
CompressedIntSetBenchmark.HashSet_Add(ItemCount: 100000) 3.48 ms 73.05 μs 3.51 ms -0.8%
HashCachingSetBenchmark.HashSet_Add(ItemCount: 100000) 4.33 ms 520.98 μs 4.48 ms -3.5%
LongSetBenchmark.HashSet_Add(ItemCount: 100000) 4.52 ms 195.80 μs 4.38 ms +3.2%
CompressedIntSetBenchmark.CompressedIntSet_Add(ItemCount: 100000) 11.04 ms 468.70 μs 10.67 ms +3.6%
HashCachingSetBenchmark.HashCachingSet_Add(ItemCount: 100000) 5.23 ms 89.51 μs 5.23 ms +0.0%
LongSetBenchmark.LongSet_Add(ItemCount: 100000) 6.09 ms 41.77 μs 6.08 ms +0.1%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_Build(ItemCount: 1000) 159.34 μs 731.1 ns 159.89 μs -0.3%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_Build(ItemCount: 1000) 3.81 ms 56.49 μs 3.90 ms -2.2%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_Build(ItemCount: 100000) 28.44 ms 275.81 μs 28.84 ms -1.4%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_Build(ItemCount: 100000) 1.82 s 211.38 ms 1.72 s +6.0%
CompressedIntSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.70 μs 9.8 ns 4.70 μs -0.0%
HashCachingSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.91 μs 173.9 ns 4.72 μs +3.9%
LongSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.80 μs 41.5 ns 4.80 μs +0.1%
CompressedIntSetBenchmark.CompressedIntSet_Contains(ItemCount: 1000) 13.48 μs 23.6 ns 13.47 μs +0.0%
HashCachingSetBenchmark.HashCachingSet_Contains(ItemCount: 1000) 2.53 μs 3.6 ns 2.53 μs -0.1%
LongSetBenchmark.LongSet_Contains(ItemCount: 1000) 2.00 μs 13.6 ns 2.01 μs -0.5%
StringKeyProbeBenchmark.HashSet_Contains(ItemCount: 1000) 18.08 μs 61.4 ns 17.97 μs +0.6%
StringKeyProbeBenchmark.CeleritySet_Contains(ItemCount: 1000) 24.28 μs 116.8 ns 24.52 μs -1.0%
CompressedIntSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.56 ms 17.75 μs 1.56 ms -0.3%
HashCachingSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.57 ms 6.19 μs 1.60 ms -2.1%
LongSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.65 ms 15.49 μs 1.64 ms +1.0%
CompressedIntSetBenchmark.CompressedIntSet_Contains(ItemCount: 100000) 8.30 ms 26.74 μs 8.33 ms -0.4%
HashCachingSetBenchmark.HashCachingSet_Contains(ItemCount: 100000) 733.03 μs 3.08 μs 725.29 μs +1.1%
LongSetBenchmark.LongSet_Contains(ItemCount: 100000) 643.86 μs 1.97 μs 640.67 μs +0.5%
StringKeyProbeBenchmark.HashSet_Contains(ItemCount: 100000) 3.53 ms 23.07 μs 3.42 ms +3.3%
StringKeyProbeBenchmark.CeleritySet_Contains(ItemCount: 100000) 5.23 ms 112.21 μs 4.71 ms +11.2% ⚠️
HashCachingSetBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.54 μs 7.2 ns 4.65 μs -2.4%
HashCachingSetBenchmark.HashCachingSet_ContainsMissing(ItemCount: 1000) 2.96 μs 2.6 ns 3.12 μs -5.2%
HashCachingSetBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.91 ms 8.33 μs 1.94 ms -1.5%
HashCachingSetBenchmark.HashCachingSet_ContainsMissing(ItemCount: 100000) 1.14 ms 4.58 μs 1.13 ms +0.4%
CompressedIntSetBenchmark.HashSet_Except(ItemCount: 1000) 56.07 μs 6.13 μs 61.32 μs -8.6%
CompressedIntSetBenchmark.CompressedIntSet_Except(ItemCount: 1000) 71.57 μs 7.65 μs 65.68 μs +9.0%
CompressedIntSetBenchmark.HashSet_Except(ItemCount: 100000) 2.54 ms 18.63 μs 2.53 ms +0.5%
CompressedIntSetBenchmark.CompressedIntSet_Except(ItemCount: 100000) 1.09 ms 22.22 μs 1.08 ms +0.9%
RobinHoodDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 14.58 μs 883.9 ns 12.70 μs +14.8%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Insert(ItemCount: 1000) 18.23 μs 717.6 ns 17.54 μs +3.9%
RobinHoodDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 4.71 ms 93.36 μs 4.70 ms +0.2%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Insert(ItemCount: 100000) 7.95 ms 653.14 μs 8.11 ms -2.0%
CompressedIntSetBenchmark.HashSet_IntersectClustered(ItemCount: 1000) 34.36 μs 2.84 μs 39.37 μs -12.7%
CompressedIntSetBenchmark.CompressedIntSet_IntersectClustered(ItemCount: 1000) 1.72 μs 330.8 ns 1.23 μs +39.9%
CompressedIntSetBenchmark.HashSet_IntersectClustered(ItemCount: 100000) 961.64 μs 10.90 μs 953.58 μs +0.8%
CompressedIntSetBenchmark.CompressedIntSet_IntersectClustered(ItemCount: 100000) 1.90 μs 352.9 ns 2.08 μs -8.8%
CompressedIntSetBenchmark.HashSet_IntersectDense(ItemCount: 1000) 47.81 μs 6.48 μs 48.03 μs -0.5%
CompressedIntSetBenchmark.CompressedIntSet_IntersectDense(ItemCount: 1000) 49.16 μs 2.48 μs 54.71 μs -10.1%
CompressedIntSetBenchmark.HashSet_IntersectDense(ItemCount: 100000) 3.02 ms 126.80 μs 3.13 ms -3.4%
CompressedIntSetBenchmark.CompressedIntSet_IntersectDense(ItemCount: 100000) 90.22 μs 27.41 μs 80.69 μs +11.8%
CompressedIntSetBenchmark.HashSet_IntersectSparse(ItemCount: 1000) 49.36 μs 3.50 μs 52.37 μs -5.7%
CompressedIntSetBenchmark.CompressedIntSet_IntersectSparse(ItemCount: 1000) 55.08 μs 6.93 μs 56.21 μs -2.0%
CompressedIntSetBenchmark.HashSet_IntersectSparse(ItemCount: 100000) 3.90 ms 34.73 μs 3.92 ms -0.7%
CompressedIntSetBenchmark.CompressedIntSet_IntersectSparse(ItemCount: 100000) 1.01 ms 56.22 μs 1.03 ms -2.1%
StringKeyProbeBenchmark.Dictionary_Lookup(ItemCount: 1000) 18.57 μs 287.0 ns 18.56 μs +0.0%
StringKeyProbeBenchmark.CelerityDictionary_Lookup(ItemCount: 1000) 26.61 μs 213.2 ns 26.70 μs -0.3%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_Lookup(ItemCount: 1000) 7.33 μs 11.5 ns 7.32 μs +0.1%
RobinHoodDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.71 μs 27.3 ns 4.70 μs +0.2%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_Lookup(ItemCount: 1000) 85.24 μs 2.19 μs 87.08 μs -2.1%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Lookup(ItemCount: 1000) 2.81 μs 7.0 ns 2.81 μs +0.2%
StringKeyProbeBenchmark.Dictionary_Lookup(ItemCount: 100000) 3.64 ms 45.41 μs 3.56 ms +2.4%
StringKeyProbeBenchmark.CelerityDictionary_Lookup(ItemCount: 100000) 5.32 ms 329.74 μs 5.25 ms +1.4%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_Lookup(ItemCount: 100000) 2.00 ms 10.92 μs 2.00 ms +0.1%
RobinHoodDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.60 ms 1.32 μs 1.56 ms +2.5%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_Lookup(ItemCount: 100000) 7.34 ms 60.26 μs 7.59 ms -3.3%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Lookup(ItemCount: 100000) 856.33 μs 6.76 μs 853.53 μs +0.3%
StringKeyProbeBenchmark.Dictionary_LookupMissing(ItemCount: 1000) 14.90 μs 54.3 ns 14.96 μs -0.3%
StringKeyProbeBenchmark.CelerityDictionary_LookupMissing(ItemCount: 1000) 28.83 μs 152.4 ns 28.18 μs +2.3%
StringKeyProbeBenchmark.Dictionary_LookupMissing(ItemCount: 100000) 3.86 ms 10.59 μs 3.84 ms +0.7%
StringKeyProbeBenchmark.CelerityDictionary_LookupMissing(ItemCount: 100000) 5.72 ms 17.95 μs 5.82 ms -1.6%
LongSetBenchmark.HashSet_Remove(ItemCount: 1000) 83.30 μs 7.14 μs 75.95 μs +9.7%
RobinHoodDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 87.41 μs 9.50 μs 82.18 μs +6.4%
LongSetBenchmark.LongSet_Remove(ItemCount: 1000) 89.08 μs 5.22 μs 83.34 μs +6.9%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Remove(ItemCount: 1000) 110.61 μs 4.17 μs 110.21 μs +0.4%
HashCachingSetBenchmark.HashSet_Remove(ItemCount: 1000) 28.20 μs 581.5 ns 26.24 μs +7.5%
HashCachingSetBenchmark.HashCachingSet_Remove(ItemCount: 1000) 115.82 μs 9.75 μs 118.23 μs -2.0%
LongSetBenchmark.HashSet_Remove(ItemCount: 100000) 2.01 ms 32.30 μs 1.99 ms +1.0%
RobinHoodDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.06 ms 10.19 μs 2.06 ms -0.3%
LongSetBenchmark.LongSet_Remove(ItemCount: 100000) 1.70 ms 245.17 μs 1.43 ms +18.7%
RobinHoodDictionaryBenchmark.RobinHoodDictionary_Remove(ItemCount: 100000) 1.73 ms 16.03 μs 1.77 ms -2.2%
HashCachingSetBenchmark.HashSet_Remove(ItemCount: 100000) 1.72 ms 15.43 μs 1.73 ms -0.3%
HashCachingSetBenchmark.HashCachingSet_Remove(ItemCount: 100000) 1.55 ms 16.20 μs 1.55 ms +0.0%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_SpanLookup(ItemCount: 1000) 30.19 μs 552.6 ns 29.99 μs +0.7%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_SpanLookup(ItemCount: 1000) 91.24 μs 134.7 ns 91.24 μs -0.0%
FrozenCelerityDictionaryBenchmark.FrozenDictionary_SpanLookup(ItemCount: 100000) 5.74 ms 49.74 μs 5.79 ms -0.8%
FrozenCelerityDictionaryBenchmark.FrozenCelerityDictionary_SpanLookup(ItemCount: 100000) 8.59 ms 32.36 μs 8.65 ms -0.6%
CompressedIntSetBenchmark.HashSet_Union(ItemCount: 1000) 35.37 μs 4.35 μs 27.26 μs +29.7%
CompressedIntSetBenchmark.CompressedIntSet_Union(ItemCount: 1000) 77.41 μs 6.97 μs 75.62 μs +2.4%
CompressedIntSetBenchmark.HashSet_Union(ItemCount: 100000) 3.95 ms 17.83 μs 3.97 ms -0.3%
CompressedIntSetBenchmark.CompressedIntSet_Union(ItemCount: 100000) 1.19 ms 17.72 μs 1.18 ms +1.1%
EnumMapBenchmark.Dictionary_Add 620.3 ns 22.0 ns 614.3 ns +1.0%
EnumMapBenchmark.EnumMap_Add 151.3 ns 0.9 ns 151.6 ns -0.2%
SmallSetBenchmark.HashSet_Add(ItemCount: 8) 176.3 ns 14.0 ns 159.7 ns +10.4%
SmallSetBenchmark.SmallSet_Add(ItemCount: 8) 44.6 ns 0.4 ns 44.9 ns -0.6%
SmallSetBenchmark.HashSet_Add(ItemCount: 64) 742.6 ns 8.0 ns 746.6 ns -0.5%
SmallSetBenchmark.SmallSet_Add(ItemCount: 64) 1.67 μs 5.1 ns 1.65 μs +1.1%
RobinHoodSetBenchmark.HashSet_Add(ItemCount: 1000) 12.03 μs 65.8 ns 12.32 μs -2.3%
TopKSketchBenchmark.Dictionary_Add(ItemCount: 1000) 13.22 μs 113.6 ns 13.23 μs -0.0%
RobinHoodSetBenchmark.RobinHoodSet_Add(ItemCount: 1000) 17.06 μs 214.5 ns 17.22 μs -0.9%
TopKSketchBenchmark.TopKSketch_Add(ItemCount: 1000) 87.39 μs 605.1 ns 87.92 μs -0.6%
RobinHoodSetBenchmark.HashSet_Add(ItemCount: 100000) 4.26 ms 487.79 μs 4.36 ms -2.2%
TopKSketchBenchmark.Dictionary_Add(ItemCount: 100000) 3.20 ms 48.26 μs 3.23 ms -0.9%
RobinHoodSetBenchmark.RobinHoodSet_Add(ItemCount: 100000) 6.18 ms 44.07 μs 6.17 ms +0.2%
TopKSketchBenchmark.TopKSketch_Add(ItemCount: 100000) 14.26 ms 23.74 μs 14.45 ms -1.3%
RadixSortBenchmark.Array_ArgSort(ItemCount: 100) 787.9 ns 3.3 ns 790.4 ns -0.3%
RadixSortBenchmark.RadixSort_ArgSort(ItemCount: 100) 2.80 μs 12.9 ns 2.80 μs +0.1%
RadixSortBenchmark.Array_ArgSort(ItemCount: 1000) 12.05 μs 274.3 ns 11.79 μs +2.2%
RadixSortBenchmark.RadixSort_ArgSort(ItemCount: 1000) 20.02 μs 327.6 ns 20.45 μs -2.1%
RadixSortBenchmark.Array_ArgSort(ItemCount: 100000) 6.25 ms 36.60 μs 6.26 ms -0.0%
RadixSortBenchmark.RadixSort_ArgSort(ItemCount: 100000) 2.07 ms 8.97 μs 2.07 ms +0.1%
RadixSortBenchmark.Array_ArgSort(ItemCount: 1000000) 73.13 ms 86.09 μs 73.04 ms +0.1%
RadixSortBenchmark.RadixSort_ArgSort(ItemCount: 1000000) 19.79 ms 26.76 μs 19.79 ms +0.0%
SmallSetBenchmark.HashSet_Contains(ItemCount: 8) 37.2 ns 0.0 ns 37.0 ns +0.5%
SmallSetBenchmark.SmallSet_Contains(ItemCount: 8) 18.9 ns 0.2 ns 18.8 ns +0.1%
SmallSetBenchmark.HashSet_Contains(ItemCount: 64) 299.1 ns 0.2 ns 310.5 ns -3.7%
SmallSetBenchmark.SmallSet_Contains(ItemCount: 64) 1.09 μs 12.0 ns 1.10 μs -0.8%
RobinHoodSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.71 μs 5.1 ns 4.72 μs -0.0%
RobinHoodSetBenchmark.RobinHoodSet_Contains(ItemCount: 1000) 2.49 μs 10.5 ns 2.50 μs -0.3%
RobinHoodSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.58 ms 14.21 μs 1.58 ms -0.2%
RobinHoodSetBenchmark.RobinHoodSet_Contains(ItemCount: 100000) 742.56 μs 7.51 μs 746.84 μs -0.6%
RobinHoodSetBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.53 μs 5.1 ns 4.45 μs +2.0%
RobinHoodSetBenchmark.RobinHoodSet_ContainsMissing(ItemCount: 1000) 2.74 μs 2.0 ns 2.74 μs -0.0%
RobinHoodSetBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.93 ms 2.63 μs 1.92 ms +0.5%
RobinHoodSetBenchmark.RobinHoodSet_ContainsMissing(ItemCount: 100000) 1.18 ms 1.68 μs 1.18 ms +0.2%
EnumMapBenchmark.Dictionary_Enumerate 50.3 ns 0.2 ns 50.4 ns -0.0%
EnumMapBenchmark.EnumMap_Enumerate 41.5 ns 1.9 ns 41.6 ns -0.3%
CelerityMultiMapBenchmark.Dictionary_Insert(ItemCount: 1000) 29.14 μs 327.7 ns 29.66 μs -1.8%
CelerityMultiMapBenchmark.CelerityMultiMap_Insert(ItemCount: 1000) 37.76 μs 731.1 ns 38.11 μs -0.9%
CelerityMultiMapBenchmark.Dictionary_Insert(ItemCount: 100000) 12.39 ms 541.62 μs 12.39 ms +0.0%
CelerityMultiMapBenchmark.CelerityMultiMap_Insert(ItemCount: 100000) 16.91 ms 169.50 μs 16.91 ms +0.0%
CountingSortBenchmark.Array_Keys(ItemCount: 100) 471.1 ns 0.3 ns 477.4 ns -1.3%
RadixSortBenchmark.Array_Keys(ItemCount: 100) 471.5 ns 0.6 ns 471.7 ns -0.0%
CountingSortBenchmark.CountingSort_Keys(ItemCount: 100) 495.5 ns 8.3 ns 493.1 ns +0.5%
RadixSortBenchmark.RadixSort_Keys(ItemCount: 100) 2.13 μs 3.3 ns 2.15 μs -1.1%
CountingSortBenchmark.Array_Keys(ItemCount: 1000) 8.20 μs 22.5 ns 8.32 μs -1.5%
RadixSortBenchmark.Array_Keys(ItemCount: 1000) 8.60 μs 123.1 ns 8.69 μs -1.0%
CountingSortBenchmark.CountingSort_Keys(ItemCount: 1000) 1.53 μs 1.3 ns 1.55 μs -1.1%
RadixSortBenchmark.RadixSort_Keys(ItemCount: 1000) 14.01 μs 6.7 ns 14.62 μs -4.2%
CountingSortBenchmark.Array_Keys(ItemCount: 100000) 3.52 ms 26.90 μs 3.51 ms +0.0%
RadixSortBenchmark.Array_Keys(ItemCount: 100000) 5.54 ms 4.89 μs 5.66 ms -2.1%
CountingSortBenchmark.CountingSort_Keys(ItemCount: 100000) 63.51 μs 433.5 ns 63.80 μs -0.4%
RadixSortBenchmark.RadixSort_Keys(ItemCount: 100000) 1.44 ms 4.05 μs 1.44 ms -0.1%
CountingSortBenchmark.Array_Keys(ItemCount: 1000000) 36.75 ms 23.82 μs 36.75 ms +0.0%
RadixSortBenchmark.Array_Keys(ItemCount: 1000000) 68.75 ms 256.39 μs 68.90 ms -0.2%
CountingSortBenchmark.CountingSort_Keys(ItemCount: 1000000) 651.62 μs 595.2 ns 649.44 μs +0.3%
RadixSortBenchmark.RadixSort_Keys(ItemCount: 1000000) 14.02 ms 197.13 μs 14.03 ms -0.1%
EnumMapBenchmark.Dictionary_Lookup 119.1 ns 0.2 ns 118.5 ns +0.5%
EnumMapBenchmark.EnumMap_Lookup 64.2 ns 0.2 ns 64.1 ns +0.0%
CelerityMultiMapBenchmark.Dictionary_Lookup(ItemCount: 1000) 5.04 μs 38.6 ns 5.02 μs +0.2%
CelerityMultiMapBenchmark.CelerityMultiMap_Lookup(ItemCount: 1000) 2.36 μs 5.9 ns 2.36 μs +0.2%
CelerityMultiMapBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.75 ms 6.45 μs 1.75 ms +0.0%
CelerityMultiMapBenchmark.CelerityMultiMap_Lookup(ItemCount: 100000) 721.53 μs 11.70 μs 733.70 μs -1.7%
CountingSortBenchmark.Array_Pairs(ItemCount: 100) 735.9 ns 17.4 ns 759.3 ns -3.1%
RadixSortBenchmark.Array_Pairs(ItemCount: 100) 705.6 ns 6.2 ns 720.8 ns -2.1%
CountingSortBenchmark.CountingSort_Pairs(ItemCount: 100) 787.8 ns 5.0 ns 756.7 ns +4.1%
RadixSortBenchmark.RadixSort_Pairs(ItemCount: 100) 2.74 μs 27.0 ns 2.68 μs +2.0%
CountingSortBenchmark.Array_Pairs(ItemCount: 1000) 13.90 μs 57.0 ns 14.09 μs -1.4%
RadixSortBenchmark.Array_Pairs(ItemCount: 1000) 11.20 μs 25.8 ns 11.45 μs -2.2%
CountingSortBenchmark.CountingSort_Pairs(ItemCount: 1000) 3.28 μs 36.6 ns 3.25 μs +1.0%
RadixSortBenchmark.RadixSort_Pairs(ItemCount: 1000) 19.71 μs 141.6 ns 19.31 μs +2.1%
CountingSortBenchmark.Array_Pairs(ItemCount: 100000) 5.11 ms 2.91 μs 5.12 ms -0.1%
RadixSortBenchmark.Array_Pairs(ItemCount: 100000) 6.25 ms 4.04 μs 6.22 ms +0.5%
CountingSortBenchmark.CountingSort_Pairs(ItemCount: 100000) 405.75 μs 2.39 μs 407.72 μs -0.5%
RadixSortBenchmark.RadixSort_Pairs(ItemCount: 100000) 2.05 ms 9.16 μs 2.04 ms +0.1%
CountingSortBenchmark.Array_Pairs(ItemCount: 1000000) 56.49 ms 213.09 μs 56.32 ms +0.3%
RadixSortBenchmark.Array_Pairs(ItemCount: 1000000) 73.67 ms 68.37 μs 73.82 ms -0.2%
CountingSortBenchmark.CountingSort_Pairs(ItemCount: 1000000) 3.70 ms 373.57 μs 4.03 ms -8.2%
RadixSortBenchmark.RadixSort_Pairs(ItemCount: 1000000) 19.52 ms 26.75 μs 19.55 ms -0.2%
EnumMapBenchmark.Dictionary_Remove 3.90 μs 463.0 ns 3.78 μs +3.4%
EnumMapBenchmark.EnumMap_Remove 1.94 μs 392.8 ns 2.08 μs -6.9%
SmallSetBenchmark.HashSet_Remove(ItemCount: 8) 500.5 ns 39.7 ns 456.3 ns +9.7%
SmallSetBenchmark.SmallSet_Remove(ItemCount: 8) 1.31 μs 237.2 ns 1.52 μs -13.8%
SmallSetBenchmark.HashSet_Remove(ItemCount: 64) 2.04 μs 39.4 ns 1.73 μs +18.1%
SmallSetBenchmark.SmallSet_Remove(ItemCount: 64) 24.36 μs 4.69 μs 30.70 μs -20.6%
CelerityMultiMapBenchmark.Dictionary_Remove(ItemCount: 1000) 29.43 μs 5.70 μs 27.59 μs +6.7%
CelerityMultiMapBenchmark.CelerityMultiMap_Remove(ItemCount: 1000) 137.35 μs 10.60 μs 136.52 μs +0.6%
RobinHoodSetBenchmark.HashSet_Remove(ItemCount: 1000) 26.92 μs 1.53 μs 33.14 μs -18.8%
RobinHoodSetBenchmark.RobinHoodSet_Remove(ItemCount: 1000) 111.74 μs 7.42 μs 106.72 μs +4.7%
CelerityMultiMapBenchmark.Dictionary_Remove(ItemCount: 100000) 1.95 ms 143.66 μs 1.99 ms -1.7%
CelerityMultiMapBenchmark.CelerityMultiMap_Remove(ItemCount: 100000) 1.77 ms 99.39 μs 1.82 ms -2.7%
RobinHoodSetBenchmark.HashSet_Remove(ItemCount: 100000) 1.71 ms 15.50 μs 1.71 ms -0.2%
RobinHoodSetBenchmark.RobinHoodSet_Remove(ItemCount: 100000) 1.38 ms 46.19 μs 1.38 ms +0.0%
TopKSketchBenchmark.Dictionary_TopK(ItemCount: 1000) 29.4 ns 0.2 ns 29.2 ns +0.8%
TopKSketchBenchmark.TopKSketch_TopK(ItemCount: 1000) 1.22 μs 7.8 ns 1.22 μs +0.4%
TopKSketchBenchmark.Dictionary_TopK(ItemCount: 100000) 31.0 ns 0.4 ns 30.6 ns +1.3%
TopKSketchBenchmark.TopKSketch_TopK(ItemCount: 100000) 1.17 μs 6.8 ns 1.19 μs -1.3%
BTreeSetBenchmark.SortedSet_Add(ItemCount: 1000) 42.02 μs 1.14 μs 41.08 μs +2.3%
PooledCeleritySetBenchmark.HashSet_Add(ItemCount: 1000) 12.08 μs 100.2 ns 11.97 μs +0.9%
BTreeSetBenchmark.BTreeSet_Add(ItemCount: 1000) 44.59 μs 2.20 μs 41.90 μs +6.4%
PooledCeleritySetBenchmark.PooledCeleritySet_Add(ItemCount: 1000) 8.52 μs 56.6 ns 8.56 μs -0.4%
BTreeSetBenchmark.SortedSet_Add(ItemCount: 100000) 20.21 ms 642.04 μs 21.33 ms -5.2%
PooledCeleritySetBenchmark.HashSet_Add(ItemCount: 100000) 4.77 ms 42.91 μs 4.88 ms -2.2%
BTreeSetBenchmark.BTreeSet_Add(ItemCount: 100000) 13.94 ms 59.86 μs 14.02 ms -0.6%
PooledCeleritySetBenchmark.PooledCeleritySet_Add(ItemCount: 100000) 2.89 ms 6.30 μs 2.88 ms +0.2%
RankSelectBitVectorBenchmark.Array_Build(ItemCount: 1024) 91.0 ns 0.3 ns 91.5 ns -0.5%
RankSelectBitVectorBenchmark.RankSelectBitVector_Build(ItemCount: 1024) 58.7 ns 0.9 ns 58.6 ns +0.3%
RankSelectBitVectorBenchmark.Array_Build(ItemCount: 1000000) 67.89 μs 582.2 ns 67.85 μs +0.1%
RankSelectBitVectorBenchmark.RankSelectBitVector_Build(ItemCount: 1000000) 85.57 μs 460.3 ns 87.32 μs -2.0%
BTreeSetBenchmark.SortedSet_Contains(ItemCount: 1000) 16.71 μs 8.9 ns 16.71 μs -0.0%
PooledCeleritySetBenchmark.HashSet_Contains(ItemCount: 1000) 4.74 μs 5.3 ns 4.74 μs -0.1%
BTreeSetBenchmark.BTreeSet_Contains(ItemCount: 1000) 17.15 μs 15.5 ns 17.45 μs -1.7%
PooledCeleritySetBenchmark.PooledCeleritySet_Contains(ItemCount: 1000) 1.97 μs 41.7 ns 1.97 μs -0.3%
BTreeSetBenchmark.SortedSet_Contains(ItemCount: 100000) 15.76 ms 45.70 μs 15.79 ms -0.2%
PooledCeleritySetBenchmark.HashSet_Contains(ItemCount: 100000) 1.58 ms 1.58 μs 1.59 ms -0.3%
BTreeSetBenchmark.BTreeSet_Contains(ItemCount: 100000) 12.79 ms 207.17 μs 12.84 ms -0.4%
PooledCeleritySetBenchmark.PooledCeleritySet_Contains(ItemCount: 100000) 577.85 μs 709.1 ns 578.52 μs -0.1%
IndexedPriorityQueueBenchmark.PriorityQueue_DecreaseKey(ItemCount: 1000) 143.74 μs 986.9 ns 144.32 μs -0.4%
IndexedPriorityQueueBenchmark.IndexedPriorityQueue_DecreaseKey(ItemCount: 1000) 265.24 μs 703.1 ns 259.81 μs +2.1%
IndexedPriorityQueueBenchmark.PriorityQueue_DecreaseKey(ItemCount: 100000) 32.56 ms 226.26 μs 32.56 ms -0.0%
IndexedPriorityQueueBenchmark.IndexedPriorityQueue_DecreaseKey(ItemCount: 100000) 55.86 ms 269.05 μs 55.74 ms +0.2%
IndexedPriorityQueueBenchmark.PriorityQueue_Enqueue(ItemCount: 1000) 4.58 μs 35.9 ns 4.60 μs -0.5%
IndexedPriorityQueueBenchmark.IndexedPriorityQueue_Enqueue(ItemCount: 1000) 29.66 μs 145.3 ns 29.46 μs +0.7%
IndexedPriorityQueueBenchmark.PriorityQueue_Enqueue(ItemCount: 100000) 1.07 ms 14.17 μs 1.08 ms -0.7%
IndexedPriorityQueueBenchmark.IndexedPriorityQueue_Enqueue(ItemCount: 100000) 6.44 ms 246.43 μs 6.35 ms +1.4%
DequeBenchmark.LinkedList_Enumerate(ItemCount: 1000) 1.37 μs 1.4 ns 1.38 μs -0.4%
DequeBenchmark.Deque_Enumerate(ItemCount: 1000) 941.9 ns 0.9 ns 941.6 ns +0.0%
DequeBenchmark.LinkedList_Enumerate(ItemCount: 100000) 135.34 μs 147.9 ns 135.50 μs -0.1%
DequeBenchmark.Deque_Enumerate(ItemCount: 100000) 93.88 μs 46.3 ns 93.90 μs -0.0%
CelerityDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 12.91 μs 239.7 ns 13.91 μs -7.2%
IntDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 13.12 μs 110.1 ns 13.34 μs -1.7%
CelerityDictionaryBenchmark.CelerityDictionary_Insert(ItemCount: 1000) 10.86 μs 584.1 ns 11.77 μs -7.7%
IntDictionaryBenchmark.IntDictionary_Insert(ItemCount: 1000) 11.40 μs 63.0 ns 11.32 μs +0.6%
CelerityDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 4.14 ms 84.57 μs 4.17 ms -0.7%
IntDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 4.18 ms 78.27 μs 4.10 ms +1.9%
CelerityDictionaryBenchmark.CelerityDictionary_Insert(ItemCount: 100000) 4.86 ms 42.41 μs 4.84 ms +0.5%
IntDictionaryBenchmark.IntDictionary_Insert(ItemCount: 100000) 4.84 ms 40.72 μs 4.85 ms -0.1%
CelerityDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.74 μs 26.8 ns 4.80 μs -1.3%
IntDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.74 μs 18.8 ns 4.74 μs +0.0%
CelerityDictionaryBenchmark.CelerityDictionary_Lookup(ItemCount: 1000) 2.49 μs 12.6 ns 2.47 μs +0.5%
IntDictionaryBenchmark.IntDictionary_Lookup(ItemCount: 1000) 2.14 μs 3.7 ns 2.19 μs -2.0%
CelerityDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.59 ms 2.10 μs 1.60 ms -0.6%
IntDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.60 ms 1.43 μs 1.59 ms +0.4%
CelerityDictionaryBenchmark.CelerityDictionary_Lookup(ItemCount: 100000) 730.84 μs 2.69 μs 732.96 μs -0.3%
IntDictionaryBenchmark.IntDictionary_Lookup(ItemCount: 100000) 667.68 μs 6.40 μs 677.06 μs -1.4%
BTreeSetBenchmark.SortedSet_Mixed(ItemCount: 1000) 99.64 μs 1.20 μs 99.13 μs +0.5%
BTreeSetBenchmark.BTreeSet_Mixed(ItemCount: 1000) 62.12 μs 304.5 ns 63.62 μs -2.4%
BTreeSetBenchmark.SortedSet_Mixed(ItemCount: 100000) 30.71 ms 1.26 ms 30.40 ms +1.0%
BTreeSetBenchmark.BTreeSet_Mixed(ItemCount: 100000) 24.68 ms 44.03 μs 24.08 ms +2.5%
DequeBenchmark.LinkedList_PushFront(ItemCount: 1000) 40.64 μs 6.17 μs 37.53 μs +8.3%
DequeBenchmark.Deque_PushFront(ItemCount: 1000) 18.87 μs 1.50 μs 20.47 μs -7.8%
DequeBenchmark.LinkedList_PushFront(ItemCount: 100000) 1.78 ms 30.57 μs 1.79 ms -0.4%
DequeBenchmark.Deque_PushFront(ItemCount: 100000) 636.51 μs 31.73 μs 720.61 μs -11.7%
DequeBenchmark.LinkedList_Queue(ItemCount: 1000) 54.65 μs 1.62 μs 61.76 μs -11.5%
DequeBenchmark.Deque_Queue(ItemCount: 1000) 36.77 μs 3.95 μs 33.37 μs +10.2%
DequeBenchmark.LinkedList_Queue(ItemCount: 100000) 4.14 ms 67.04 μs 4.11 ms +0.8%
DequeBenchmark.Deque_Queue(ItemCount: 100000) 474.59 μs 111.71 μs 413.07 μs +14.9%
BTreeSetBenchmark.SortedSet_RangeScan(ItemCount: 1000) 170.1 ns 3.4 ns 171.9 ns -1.1%
BTreeSetBenchmark.BTreeSet_RangeScan(ItemCount: 1000) 74.2 ns 0.2 ns 74.3 ns -0.1%
BTreeSetBenchmark.SortedSet_RangeScan(ItemCount: 100000) 10.10 μs 382.5 ns 9.40 μs +7.4%
BTreeSetBenchmark.BTreeSet_RangeScan(ItemCount: 100000) 5.19 μs 17.0 ns 5.20 μs -0.2%
RankSelectBitVectorBenchmark.Array_RankEarly(ItemCount: 1024) 1.23 μs 1.8 ns 1.23 μs -0.0%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankEarly(ItemCount: 1024) 1.88 μs 1.7 ns 1.88 μs -0.0%
RankSelectBitVectorBenchmark.Array_RankEarly(ItemCount: 1000000) 32.73 μs 64.0 ns 32.76 μs -0.1%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankEarly(ItemCount: 1000000) 1.88 μs 2.4 ns 1.88 μs +0.1%
RankSelectBitVectorBenchmark.Array_RankLate(ItemCount: 1024) 6.44 μs 7.0 ns 6.43 μs +0.0%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankLate(ItemCount: 1024) 1.88 μs 0.8 ns 1.88 μs -0.0%
RankSelectBitVectorBenchmark.Array_RankLate(ItemCount: 1000000) 4.87 ms 8.47 μs 4.87 ms +0.0%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankLate(ItemCount: 1000000) 1.97 μs 2.9 ns 1.88 μs +5.0%
RankSelectBitVectorBenchmark.Array_RankMid(ItemCount: 1024) 4.86 μs 8.1 ns 4.87 μs -0.1%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankMid(ItemCount: 1024) 1.88 μs 1.1 ns 1.88 μs -0.0%
RankSelectBitVectorBenchmark.Array_RankMid(ItemCount: 1000000) 2.47 ms 1.44 μs 2.48 ms -0.1%
RankSelectBitVectorBenchmark.RankSelectBitVector_RankMid(ItemCount: 1000000) 1.88 μs 0.9 ns 1.88 μs -0.0%
BTreeSetBenchmark.SortedSet_Remove(ItemCount: 1000) 732.84 μs 13.14 μs 735.89 μs -0.4%
CelerityDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 83.53 μs 9.31 μs 82.57 μs +1.2%
IntDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 82.18 μs 9.21 μs 85.80 μs -4.2%
PooledCeleritySetBenchmark.HashSet_Remove(ItemCount: 1000) 35.08 μs 1.48 μs 26.14 μs +34.2% ⚠️
BTreeSetBenchmark.BTreeSet_Remove(ItemCount: 1000) 271.90 μs 12.66 μs 273.56 μs -0.6%
CelerityDictionaryBenchmark.CelerityDictionary_Remove(ItemCount: 1000) 125.70 μs 4.48 μs 124.33 μs +1.1%
IntDictionaryBenchmark.IntDictionary_Remove(ItemCount: 1000) 98.32 μs 10.24 μs 89.22 μs +10.2%
PooledCeleritySetBenchmark.PooledCeleritySet_Remove(ItemCount: 1000) 121.65 μs 6.75 μs 114.14 μs +6.6%
BTreeSetBenchmark.SortedSet_Remove(ItemCount: 100000) 25.04 ms 82.74 μs 25.41 ms -1.4%
CelerityDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.04 ms 12.46 μs 2.05 ms -0.6%
IntDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.04 ms 19.83 μs 2.04 ms -0.2%
PooledCeleritySetBenchmark.HashSet_Remove(ItemCount: 100000) 1.70 ms 13.45 μs 1.72 ms -1.1%
BTreeSetBenchmark.BTreeSet_Remove(ItemCount: 100000) 15.08 ms 37.84 μs 15.35 ms -1.8%
CelerityDictionaryBenchmark.CelerityDictionary_Remove(ItemCount: 100000) 1.56 ms 20.28 μs 1.59 ms -2.3%
IntDictionaryBenchmark.IntDictionary_Remove(ItemCount: 100000) 1.56 ms 20.24 μs 1.55 ms +0.7%
PooledCeleritySetBenchmark.PooledCeleritySet_Remove(ItemCount: 100000) 1.31 ms 54.48 μs 1.37 ms -4.3%
RankSelectBitVectorBenchmark.Array_Select(ItemCount: 1024) 12.98 μs 136.8 ns 12.97 μs +0.1%
RankSelectBitVectorBenchmark.RankSelectBitVector_Select(ItemCount: 1024) 11.40 μs 6.7 ns 11.40 μs +0.0%
RankSelectBitVectorBenchmark.Array_Select(ItemCount: 1000000) 4.22 ms 3.04 μs 4.23 ms -0.3%
RankSelectBitVectorBenchmark.RankSelectBitVector_Select(ItemCount: 1000000) 25.35 μs 310.3 ns 25.48 μs -0.5%
TrieBenchmark.Dictionary_Add(ItemCount: 1000) 45.27 μs 6.49 μs 32.96 μs +37.4%
TrieBenchmark.Trie_Add(ItemCount: 1000) 559.20 μs 17.80 μs 451.72 μs +23.8%
BTreeDictionaryBenchmark.SortedDictionary_Add(ItemCount: 1000) 61.06 μs 1.19 μs 64.54 μs -5.4%
IntSetBenchmark.HashSet_Add(ItemCount: 1000) 12.21 μs 59.4 ns 13.17 μs -7.2%
SwissSetBenchmark.HashSet_Add(ItemCount: 1000) 12.77 μs 215.8 ns 12.26 μs +4.2%
BTreeDictionaryBenchmark.BTreeDictionary_Add(ItemCount: 1000) 54.69 μs 388.3 ns 52.90 μs +3.4%
IntSetBenchmark.IntSet_Add(ItemCount: 1000) 8.39 μs 25.5 ns 8.62 μs -2.7%
SwissSetBenchmark.SwissSet_Add(ItemCount: 1000) 26.79 μs 199.9 ns 26.26 μs +2.0%
TrieBenchmark.Dictionary_Add(ItemCount: 100000) 5.35 ms 1.41 ms 4.73 ms +13.2%
TrieBenchmark.Trie_Add(ItemCount: 100000) 27.08 ms 363.96 μs 26.17 ms +3.5%
BTreeDictionaryBenchmark.SortedDictionary_Add(ItemCount: 100000) 23.46 ms 232.01 μs 23.69 ms -0.9%
IntSetBenchmark.HashSet_Add(ItemCount: 100000) 5.02 ms 123.68 μs 5.04 ms -0.3%
SwissSetBenchmark.HashSet_Add(ItemCount: 100000) 4.87 ms 112.91 μs 4.73 ms +2.8%
BTreeDictionaryBenchmark.BTreeDictionary_Add(ItemCount: 100000) 16.22 ms 153.91 μs 16.22 ms -0.1%
IntSetBenchmark.IntSet_Add(ItemCount: 100000) 3.15 ms 21.82 μs 3.16 ms -0.3%
SwissSetBenchmark.SwissSet_Add(ItemCount: 100000) 4.68 ms 35.51 μs 4.51 ms +3.8%
DisjointSetBenchmark.Dictionary_Components(ItemCount: 1000) 18.17 μs 69.8 ns 18.23 μs -0.3%
DisjointSetBenchmark.DisjointSet_Components(ItemCount: 1000) 16.07 μs 56.6 ns 16.15 μs -0.5%
DisjointSetBenchmark.Dictionary_Components(ItemCount: 100000) 4.27 ms 60.72 μs 4.22 ms +1.2%
DisjointSetBenchmark.DisjointSet_Components(ItemCount: 100000) 3.30 ms 110.38 μs 3.31 ms -0.4%
DisjointSetBenchmark.Dictionary_Connected(ItemCount: 1000) 9.44 μs 254.7 ns 9.41 μs +0.3%
DisjointSetBenchmark.DisjointSet_Connected(ItemCount: 1000) 12.22 μs 33.1 ns 12.20 μs +0.2%
DisjointSetBenchmark.Dictionary_Connected(ItemCount: 100000) 252.38 μs 3.61 μs 256.59 μs -1.6%
DisjointSetBenchmark.DisjointSet_Connected(ItemCount: 100000) 340.00 μs 2.57 μs 340.94 μs -0.3%
IntSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.74 μs 4.9 ns 4.74 μs +0.0%
SwissSetBenchmark.HashSet_Contains(ItemCount: 1000) 4.75 μs 40.8 ns 4.74 μs +0.2%
IntSetBenchmark.IntSet_Contains(ItemCount: 1000) 1.79 μs 19.0 ns 1.80 μs -0.1%
SwissSetBenchmark.SwissSet_Contains(ItemCount: 1000) 2.87 μs 4.1 ns 2.86 μs +0.1%
IntSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.56 ms 14.71 μs 1.55 ms +0.2%
SwissSetBenchmark.HashSet_Contains(ItemCount: 100000) 1.57 ms 14.85 μs 1.56 ms +0.7%
IntSetBenchmark.IntSet_Contains(ItemCount: 100000) 575.01 μs 440.4 ns 570.85 μs +0.7%
SwissSetBenchmark.SwissSet_Contains(ItemCount: 100000) 640.71 μs 7.28 μs 600.79 μs +6.6%
SwissSetBenchmark.HashSet_ContainsMissing(ItemCount: 1000) 4.54 μs 3.0 ns 4.54 μs -0.0%
SwissSetBenchmark.SwissSet_ContainsMissing(ItemCount: 1000) 2.37 μs 3.3 ns 2.37 μs +0.0%
SwissSetBenchmark.HashSet_ContainsMissing(ItemCount: 100000) 1.95 ms 6.15 μs 1.93 ms +0.8%
SwissSetBenchmark.SwissSet_ContainsMissing(ItemCount: 100000) 346.52 μs 8.21 μs 358.33 μs -3.3%
StringInternTableBenchmark.Dictionary_Dedupe(ItemCount: 1000) 34.00 μs 148.2 ns 33.58 μs +1.2%
StringInternTableBenchmark.StringInternTable_Dedupe(ItemCount: 1000) 35.60 μs 44.9 ns 35.74 μs -0.4%
StringInternTableBenchmark.Dictionary_Dedupe(ItemCount: 100000) 3.32 ms 17.93 μs 3.24 ms +2.6%
StringInternTableBenchmark.StringInternTable_Dedupe(ItemCount: 100000) 3.19 ms 5.50 μs 3.19 ms +0.0%
LongDictionaryBenchmark.Dictionary_Insert(ItemCount: 1000) 14.71 μs 324.9 ns 14.33 μs +2.7%
LongDictionaryBenchmark.LongDictionary_Insert(ItemCount: 1000) 11.07 μs 70.6 ns 11.29 μs -1.9%
LongDictionaryBenchmark.Dictionary_Insert(ItemCount: 100000) 4.91 ms 28.34 μs 4.94 ms -0.6%
LongDictionaryBenchmark.LongDictionary_Insert(ItemCount: 100000) 6.91 ms 165.78 μs 6.84 ms +1.1%
BTreeDictionaryBenchmark.SortedDictionary_Lookup(ItemCount: 1000) 35.17 μs 224.0 ns 35.09 μs +0.2%
LongDictionaryBenchmark.Dictionary_Lookup(ItemCount: 1000) 4.89 μs 26.9 ns 4.89 μs +0.1%
StringInternTableBenchmark.HashSet_Lookup(ItemCount: 1000) 33.07 μs 504.1 ns 32.45 μs +1.9%
TrieBenchmark.Dictionary_Lookup(ItemCount: 1000) 12.97 μs 585.1 ns 13.12 μs -1.2%
BTreeDictionaryBenchmark.BTreeDictionary_Lookup(ItemCount: 1000) 25.42 μs 95.2 ns 25.36 μs +0.2%
LongDictionaryBenchmark.LongDictionary_Lookup(ItemCount: 1000) 2.27 μs 5.1 ns 2.27 μs +0.1%
StringInternTableBenchmark.StringInternTable_Lookup(ItemCount: 1000) 31.39 μs 18.1 ns 31.41 μs -0.1%
TrieBenchmark.Trie_Lookup(ItemCount: 1000) 41.20 μs 302.6 ns 40.93 μs +0.7%
BTreeDictionaryBenchmark.SortedDictionary_Lookup(ItemCount: 100000) 18.10 ms 208.97 μs 17.90 ms +1.1%
LongDictionaryBenchmark.Dictionary_Lookup(ItemCount: 100000) 1.57 ms 601.5 ns 1.60 ms -1.4%
StringInternTableBenchmark.HashSet_Lookup(ItemCount: 100000) 3.43 ms 58.22 μs 3.21 ms +7.0%
TrieBenchmark.Dictionary_Lookup(ItemCount: 100000) 2.68 ms 13.22 μs 2.67 ms +0.3%
BTreeDictionaryBenchmark.BTreeDictionary_Lookup(ItemCount: 100000) 13.16 ms 167.41 μs 13.11 ms +0.4%
LongDictionaryBenchmark.LongDictionary_Lookup(ItemCount: 100000) 701.51 μs 2.41 μs 739.39 μs -5.1%
StringInternTableBenchmark.StringInternTable_Lookup(ItemCount: 100000) 3.17 ms 2.14 μs 3.16 ms +0.2%
TrieBenchmark.Trie_Lookup(ItemCount: 100000) 8.41 ms 80.48 μs 8.22 ms +2.4%
BTreeDictionaryBenchmark.SortedDictionary_Mixed(ItemCount: 1000) 196.10 μs 1.15 μs 190.34 μs +3.0%
BTreeDictionaryBenchmark.BTreeDictionary_Mixed(ItemCount: 1000) 84.19 μs 3.01 μs 89.97 μs -6.4%
BTreeDictionaryBenchmark.SortedDictionary_Mixed(ItemCount: 100000) 50.17 ms 430.45 μs 48.38 ms +3.7%
BTreeDictionaryBenchmark.BTreeDictionary_Mixed(ItemCount: 100000) 26.49 ms 76.29 μs 26.36 ms +0.5%
TrieBenchmark.Dictionary_PrefixMatch(ItemCount: 1000) 73.30 μs 106.7 ns 73.27 μs +0.0%
TrieBenchmark.Trie_PrefixMatch(ItemCount: 1000) 57.23 μs 1.59 μs 55.49 μs +3.1%
TrieBenchmark.Dictionary_PrefixMatch(ItemCount: 100000) 7.37 ms 15.80 μs 7.36 ms +0.0%
TrieBenchmark.Trie_PrefixMatch(ItemCount: 100000) 6.76 ms 45.83 μs 6.16 ms +9.7%
BTreeDictionaryBenchmark.SortedDictionary_RangeScan(ItemCount: 1000) 4.48 μs 26.4 ns 4.50 μs -0.4%
BTreeDictionaryBenchmark.BTreeDictionary_RangeScan(ItemCount: 1000) 78.2 ns 0.2 ns 79.3 ns -1.4%
BTreeDictionaryBenchmark.SortedDictionary_RangeScan(ItemCount: 100000) 1.25 ms 10.31 μs 1.24 ms +0.9%
BTreeDictionaryBenchmark.BTreeDictionary_RangeScan(ItemCount: 100000) 5.78 μs 7.7 ns 5.77 μs +0.1%
BTreeDictionaryBenchmark.SortedDictionary_Remove(ItemCount: 1000) 789.51 μs 17.04 μs 773.95 μs +2.0%
IntSetBenchmark.HashSet_Remove(ItemCount: 1000) 30.44 μs 4.46 μs 32.18 μs -5.4%
LongDictionaryBenchmark.Dictionary_Remove(ItemCount: 1000) 88.56 μs 9.16 μs 93.70 μs -5.5%
BTreeDictionaryBenchmark.BTreeDictionary_Remove(ItemCount: 1000) 306.42 μs 13.02 μs 313.38 μs -2.2%
IntSetBenchmark.IntSet_Remove(ItemCount: 1000) 85.68 μs 6.52 μs 88.81 μs -3.5%
LongDictionaryBenchmark.LongDictionary_Remove(ItemCount: 1000) 88.07 μs 4.74 μs 94.43 μs -6.7%
SwissSetBenchmark.HashSet_Remove(ItemCount: 1000) 27.19 μs 1.41 μs 32.79 μs -17.1%
SwissSetBenchmark.SwissSet_Remove(ItemCount: 1000) 74.40 μs 5.72 μs 74.48 μs -0.1%
BTreeDictionaryBenchmark.SortedDictionary_Remove(ItemCount: 100000) 27.00 ms 690.56 μs 26.62 ms +1.4%
IntSetBenchmark.HashSet_Remove(ItemCount: 100000) 1.72 ms 21.29 μs 1.70 ms +1.1%
LongDictionaryBenchmark.Dictionary_Remove(ItemCount: 100000) 2.01 ms 26.93 μs 2.39 ms -15.9%
BTreeDictionaryBenchmark.BTreeDictionary_Remove(ItemCount: 100000) 18.22 ms 119.56 μs 18.99 ms -4.0%
IntSetBenchmark.IntSet_Remove(ItemCount: 100000) 1.33 ms 13.69 μs 1.34 ms -0.4%
LongDictionaryBenchmark.LongDictionary_Remove(ItemCount: 100000) 2.84 ms 2.22 ms 6.96 ms -59.2%
SwissSetBenchmark.HashSet_Remove(ItemCount: 100000) 1.71 ms 16.72 μs 1.71 ms +0.1%
SwissSetBenchmark.SwissSet_Remove(ItemCount: 100000) 1.08 ms 12.49 μs 1.08 ms -0.0%
TrieBenchmark.Dictionary_SpanLookup(ItemCount: 1000) 39.63 μs 123.7 ns 39.92 μs -0.7%
TrieBenchmark.Trie_SpanLookup(ItemCount: 1000) 43.50 μs 379.2 ns 43.10 μs +0.9%
TrieBenchmark.Dictionary_SpanLookup(ItemCount: 100000) 5.58 ms 9.72 μs 5.60 ms -0.4%
TrieBenchmark.Trie_SpanLookup(ItemCount: 100000) 8.13 ms 31.50 μs 8.11 ms +0.2%
DisjointSetBenchmark.Dictionary_Union(ItemCount: 1000) 94.62 μs 2.58 μs 97.18 μs -2.6%
DisjointSetBenchmark.DisjointSet_Union(ItemCount: 1000) 26.42 μs 182.5 ns 27.19 μs -2.9%
DisjointSetBenchmark.Dictionary_Union(ItemCount: 100000) 44.52 ms 2.43 ms 40.82 ms +9.1%
DisjointSetBenchmark.DisjointSet_Union(ItemCount: 100000) 8.14 ms 50.19 μs 8.06 ms +0.9%
Hashers (111)
Benchmark This PR StdDev main Δ
StringHasherBenchmark.Bcl_GetHashCode(Shape: ShortAscii) 16.66 μs 13.3 ns 16.66 μs +0.0%
StringHasherBenchmark.EqualityComparer_Default(Shape: ShortAscii) 16.62 μs 11.9 ns 16.63 μs -0.1%
StringHasherBenchmark.Djb2(Shape: ShortAscii) 24.64 μs 9.1 ns 24.66 μs -0.1%
StringHasherBenchmark.Djb2A(Shape: ShortAscii) 24.65 μs 19.6 ns 24.65 μs +0.0%
StringHasherBenchmark.Sdbm(Shape: ShortAscii) 35.23 μs 40.3 ns 35.23 μs +0.0%
StringHasherBenchmark.Elf(Shape: ShortAscii) 43.62 μs 29.4 ns 43.63 μs -0.0%
StringHasherBenchmark.Crc32(Shape: ShortAscii) 55.21 μs 37.2 ns 55.22 μs -0.0%
StringHasherBenchmark.Adler32(Shape: ShortAscii) 106.85 μs 88.1 ns 106.84 μs +0.0%
StringHasherBenchmark.FnV1(Shape: ShortAscii) 28.48 μs 15.3 ns 28.47 μs +0.0%
StringHasherBenchmark.FnV1_64(Shape: ShortAscii) 29.14 μs 7.2 ns 29.23 μs -0.3%
StringHasherBenchmark.FnV1A(Shape: ShortAscii) 12.32 μs 126.9 ns 12.36 μs -0.3%
StringHasherBenchmark.FnV1A_Full(Shape: ShortAscii) 25.00 μs 17.2 ns 25.01 μs -0.0%
StringHasherBenchmark.FnV1A_64(Shape: ShortAscii) 31.94 μs 11.2 ns 31.95 μs -0.1%
StringHasherBenchmark.JenkinsOaat(Shape: ShortAscii) 40.70 μs 53.2 ns 40.70 μs +0.0%
StringHasherBenchmark.Murmur2(Shape: ShortAscii) 16.65 μs 11.8 ns 16.66 μs -0.0%
StringHasherBenchmark.Murmur3(Shape: ShortAscii) 20.34 μs 8.5 ns 20.33 μs +0.0%
StringHasherBenchmark.XxHash32(Shape: ShortAscii) 17.74 μs 35.6 ns 17.74 μs +0.0%
StringHasherBenchmark.XxHash64(Shape: ShortAscii) 19.68 μs 24.4 ns 19.68 μs -0.0%
StringHasherBenchmark.XxHash3(Shape: ShortAscii) 16.93 μs 11.4 ns 16.96 μs -0.2%
StringHasherBenchmark.CityHash64(Shape: ShortAscii) 17.02 μs 21.3 ns 17.04 μs -0.1%
StringHasherBenchmark.MetroHash64(Shape: ShortAscii) 17.29 μs 6.1 ns 17.30 μs -0.1%
StringHasherBenchmark.SipHash13(Shape: ShortAscii) 30.98 μs 20.8 ns 30.99 μs -0.0%
StringHasherBenchmark.SipHash24(Shape: ShortAscii) 43.71 μs 15.9 ns 43.75 μs -0.1%
StringHasherBenchmark.HalfSipHash24(Shape: ShortAscii) 56.55 μs 45.1 ns 56.57 μs -0.0%
StringHasherBenchmark.HighwayHash64(Shape: ShortAscii) 447.63 μs 9.95 μs 451.01 μs -0.7%
StringHasherBenchmark.XxHash64_Hash64(Shape: ShortAscii) 19.67 μs 15.7 ns 19.67 μs +0.0%
StringHasherBenchmark.SipHash24_Hash64(Shape: ShortAscii) 42.67 μs 20.0 ns 42.66 μs +0.0%
StringHasherBenchmark.Bcl_GetHashCode(Shape: LongAscii) 108.15 μs 29.7 ns 108.16 μs -0.0%
StringHasherBenchmark.EqualityComparer_Default(Shape: LongAscii) 108.48 μs 77.7 ns 108.49 μs -0.0%
StringHasherBenchmark.Djb2(Shape: LongAscii) 254.72 μs 138.0 ns 254.69 μs +0.0%
StringHasherBenchmark.Djb2A(Shape: LongAscii) 254.69 μs 102.2 ns 254.67 μs +0.0%
StringHasherBenchmark.Sdbm(Shape: LongAscii) 343.52 μs 95.2 ns 343.55 μs -0.0%
StringHasherBenchmark.Elf(Shape: LongAscii) 624.94 μs 396.9 ns 624.84 μs +0.0%
StringHasherBenchmark.Crc32(Shape: LongAscii) 663.49 μs 545.9 ns 663.26 μs +0.0%
StringHasherBenchmark.Adler32(Shape: LongAscii) 883.08 μs 368.9 ns 882.78 μs +0.0%
StringHasherBenchmark.FnV1(Shape: LongAscii) 317.89 μs 270.6 ns 317.85 μs +0.0%
StringHasherBenchmark.FnV1_64(Shape: LongAscii) 320.31 μs 164.8 ns 320.39 μs -0.0%
StringHasherBenchmark.FnV1A(Shape: LongAscii) 134.23 μs 154.9 ns 134.19 μs +0.0%
StringHasherBenchmark.FnV1A_Full(Shape: LongAscii) 314.15 μs 483.6 ns 314.13 μs +0.0%
StringHasherBenchmark.FnV1A_64(Shape: LongAscii) 321.69 μs 237.9 ns 321.58 μs +0.0%
StringHasherBenchmark.JenkinsOaat(Shape: LongAscii) 421.82 μs 152.3 ns 421.95 μs -0.0%
StringHasherBenchmark.Murmur2(Shape: LongAscii) 98.64 μs 1.57 μs 98.63 μs +0.0%
StringHasherBenchmark.Murmur3(Shape: LongAscii) 117.10 μs 113.3 ns 117.12 μs -0.0%
StringHasherBenchmark.XxHash32(Shape: LongAscii) 77.10 μs 154.9 ns 77.09 μs +0.0%
StringHasherBenchmark.XxHash64(Shape: LongAscii) 94.67 μs 88.5 ns 94.62 μs +0.1%
StringHasherBenchmark.XxHash3(Shape: LongAscii) 92.75 μs 51.6 ns 93.00 μs -0.3%
StringHasherBenchmark.CityHash64(Shape: LongAscii) 134.71 μs 78.2 ns 134.68 μs +0.0%
StringHasherBenchmark.MetroHash64(Shape: LongAscii) 81.83 μs 90.1 ns 82.17 μs -0.4%
StringHasherBenchmark.SipHash13(Shape: LongAscii) 116.17 μs 69.5 ns 116.38 μs -0.2%
StringHasherBenchmark.SipHash24(Shape: LongAscii) 171.39 μs 393.9 ns 171.34 μs +0.0%
StringHasherBenchmark.HalfSipHash24(Shape: LongAscii) 273.05 μs 328.5 ns 272.99 μs +0.0%
StringHasherBenchmark.HighwayHash64(Shape: LongAscii) 818.15 μs 17.62 μs 789.57 μs +3.6%
StringHasherBenchmark.XxHash64_Hash64(Shape: LongAscii) 92.23 μs 89.6 ns 92.23 μs +0.0%
StringHasherBenchmark.SipHash24_Hash64(Shape: LongAscii) 171.65 μs 564.9 ns 171.49 μs +0.1%
StringHasherBenchmark.Bcl_GetHashCode(Shape: NonAscii) 25.07 μs 11.7 ns 25.09 μs -0.1%
StringHasherBenchmark.EqualityComparer_Default(Shape: NonAscii) 25.02 μs 25.3 ns 25.02 μs -0.0%
StringHasherBenchmark.Djb2(Shape: NonAscii) 45.54 μs 18.4 ns 45.54 μs -0.0%
StringHasherBenchmark.Djb2A(Shape: NonAscii) 45.55 μs 35.6 ns 45.55 μs +0.0%
StringHasherBenchmark.Sdbm(Shape: NonAscii) 66.30 μs 51.1 ns 66.27 μs +0.0%
StringHasherBenchmark.Elf(Shape: NonAscii) 88.11 μs 39.1 ns 88.10 μs +0.0%
StringHasherBenchmark.Crc32(Shape: NonAscii) 112.09 μs 62.5 ns 112.19 μs -0.1%
StringHasherBenchmark.Adler32(Shape: NonAscii) 191.69 μs 91.7 ns 191.79 μs -0.1%
StringHasherBenchmark.FnV1(Shape: NonAscii) 51.13 μs 10.4 ns 51.15 μs -0.0%
StringHasherBenchmark.FnV1_64(Shape: NonAscii) 52.64 μs 37.3 ns 52.67 μs -0.1%
StringHasherBenchmark.FnV1A(Shape: NonAscii) 22.93 μs 32.5 ns 22.91 μs +0.1%
StringHasherBenchmark.FnV1A_Full(Shape: NonAscii) 47.19 μs 51.0 ns 47.20 μs -0.0%
StringHasherBenchmark.FnV1A_64(Shape: NonAscii) 54.11 μs 29.8 ns 54.13 μs -0.0%
StringHasherBenchmark.JenkinsOaat(Shape: NonAscii) 77.04 μs 76.0 ns 77.08 μs -0.0%
StringHasherBenchmark.Murmur2(Shape: NonAscii) 24.68 μs 15.6 ns 24.68 μs -0.0%
StringHasherBenchmark.Murmur3(Shape: NonAscii) 30.14 μs 13.6 ns 30.14 μs +0.0%
StringHasherBenchmark.XxHash32(Shape: NonAscii) 24.89 μs 25.9 ns 24.89 μs +0.0%
StringHasherBenchmark.XxHash64(Shape: NonAscii) 32.79 μs 52.9 ns 32.73 μs +0.2%
StringHasherBenchmark.XxHash3(Shape: NonAscii) 26.31 μs 14.1 ns 26.69 μs -1.4%
StringHasherBenchmark.CityHash64(Shape: NonAscii) 23.72 μs 21.8 ns 23.79 μs -0.3%
StringHasherBenchmark.MetroHash64(Shape: NonAscii) 27.53 μs 60.2 ns 27.51 μs +0.1%
StringHasherBenchmark.SipHash13(Shape: NonAscii) 40.00 μs 19.8 ns 39.99 μs +0.0%
StringHasherBenchmark.SipHash24(Shape: NonAscii) 58.40 μs 112.9 ns 58.38 μs +0.0%
StringHasherBenchmark.HalfSipHash24(Shape: NonAscii) 79.52 μs 65.5 ns 79.50 μs +0.0%
StringHasherBenchmark.HighwayHash64(Shape: NonAscii) 492.23 μs 938.0 ns 667.87 μs -26.3%
StringHasherBenchmark.XxHash64_Hash64(Shape: NonAscii) 31.14 μs 49.4 ns 31.13 μs +0.0%
StringHasherBenchmark.SipHash24_Hash64(Shape: NonAscii) 57.05 μs 36.1 ns 57.04 μs +0.0%
IntegerHasherBenchmark.Guid_Bcl 1.49 μs 9.9 ns 1.48 μs +0.8%
IntegerHasherBenchmark.Guid_EqualityComparer 3.44 μs 40.5 ns 3.44 μs +0.0%
IntegerHasherBenchmark.Guid_Celerity 9.14 μs 18.6 ns 9.14 μs +0.1%
IntegerHasherBenchmark.Guid_Celerity_Hash64 9.14 μs 52.5 ns 9.14 μs +0.0%
IntegerHasherBenchmark.Int32_Bcl 774.4 ns 1.1 ns 774.2 ns +0.0%
IntegerHasherBenchmark.Int32_EqualityComparer 765.4 ns 3.0 ns 763.9 ns +0.2%
IntegerHasherBenchmark.Int32_Identity 763.7 ns 0.8 ns 769.3 ns -0.7%
IntegerHasherBenchmark.Int32_WangNaive 1.41 μs 0.6 ns 1.41 μs +0.0%
IntegerHasherBenchmark.Int32_Wang 3.42 μs 5.9 ns 3.42 μs +0.0%
IntegerHasherBenchmark.Int32_Murmur3 3.05 μs 1.3 ns 3.04 μs +0.4%
IntegerHasherBenchmark.Int64_Bcl 1.68 μs 0.3 ns 1.68 μs -0.1%
IntegerHasherBenchmark.Int64_EqualityComparer 1.41 μs 0.7 ns 1.41 μs +0.0%
IntegerHasherBenchmark.Int64_Identity 762.8 ns 0.5 ns 765.2 ns -0.3%
IntegerHasherBenchmark.Int64_WangNaive 2.11 μs 2.6 ns 2.11 μs +0.0%
IntegerHasherBenchmark.Int64_Wang 4.70 μs 5.1 ns 4.70 μs +0.1%
IntegerHasherBenchmark.Int64_Murmur3 2.68 μs 1.5 ns 2.68 μs -0.0%
IntegerHasherBenchmark.Int64_Wang_Hash64 4.70 μs 2.1 ns 4.70 μs -0.1%
IntegerHasherBenchmark.Int64_Murmur3_Hash64 2.68 μs 3.8 ns 2.68 μs +0.1%
IntegerHasherBenchmark.UInt32_Bcl 774.6 ns 1.3 ns 771.2 ns +0.4%
IntegerHasherBenchmark.UInt32_EqualityComparer 764.2 ns 1.0 ns 763.8 ns +0.1%
IntegerHasherBenchmark.UInt32_WangNaive 1.41 μs 0.4 ns n/a 🆕 new
IntegerHasherBenchmark.UInt32_Wang 3.42 μs 2.7 ns 3.42 μs -0.0%
IntegerHasherBenchmark.UInt32_Murmur3 3.05 μs 1.3 ns 3.05 μs +0.0%
IntegerHasherBenchmark.UInt64_Bcl 1.68 μs 0.4 ns 1.68 μs +0.0%
IntegerHasherBenchmark.UInt64_EqualityComparer 1.41 μs 0.5 ns 1.41 μs -0.0%
IntegerHasherBenchmark.UInt64_Murmur3 2.68 μs 1.9 ns n/a 🆕 new
IntegerHasherBenchmark.UInt64_Wang 4.70 μs 3.4 ns 4.70 μs +0.0%
IntegerHasherBenchmark.UInt64_WangNaive 2.10 μs 1.3 ns 2.10 μs -0.0%
IntegerHasherBenchmark.UInt64_Murmur3_Hash64 2.68 μs 2.0 ns n/a 🆕 new
IntegerHasherBenchmark.UInt64_Wang_Hash64 4.70 μs 2.2 ns 4.70 μs -0.0%

Same-runner A/B (sharded 8-way): main (1debf52) and this PR were built and benchmarked back-to-back on the same runner per shard, so hardware variance cancels out. ⚠️ = PR mean is at least 10% slower than main and the gap exceeds 3σ of the two measurements' combined standard deviation; ✅ = correspondingly faster.

Observed spread of this run — |Δ| across all 754 paired rows: p50 0.5%, p90 6.6%, p95 11.2% (nearest-rank). A pull request usually touches a handful of these, so this is mostly the runner's own drift between the two slices — but a change to a shared primitive moves many rows at once and would raise these figures itself, so read it as the run's spread rather than as a floor the PR cannot have caused. A flag that does not stand out against it is worth re-running before acting on.

@marius-bughiu

Copy link
Copy Markdown
Owner Author

CI is green — all 21 checks pass. Two things from the benchmark comment worth reading before the ⚠️ count is taken at face value.

The rename behaved as predicted. The three arms render as 🆕 new with n/a on the base side, and are not counted toward the errored total:

Benchmark This PR main
IntegerHasherBenchmark.UInt32_WangNaive 1.41 μs 🆕 new
IntegerHasherBenchmark.UInt64_Murmur3 2.68 μs 🆕 new
IntegerHasherBenchmark.UInt64_Murmur3_Hash64 2.68 μs 🆕 new

The 3 flagged regressions are not this PR. I checked rather than asserting it:

Flagged row Δ Why the diff cannot reach it
PooledCeleritySetBenchmark.HashSet_Remove(1000) +34.2% A pure BCL armHashSet<int>.Remove, no Celerity code on the path at all
SortedSpanBenchmark.SortedSpan_Except(1000) +20.9% Celerity.Primitives; a sorted-span merge, no hasher involved
StringKeyProbeBenchmark.CeleritySet_Contains(100000) +11.2% String hashers, untouched by this branch — and sits exactly at the runs p95

grep -lE "UInt32\|UInt64" over all three benchmark sources returns nothing: none of them instantiates an unsigned hasher. The shipped-IL change here is two new struct types nothing else references, plus two obsolete structs whose Hash bodies now delegate to them; every other edit is documentation or the benchmark project. A BCL-only arm moving 34% is the tell — that is the runner, not the branch.

The runs own spread agrees: p50 0.5%, p90 6.6%, p95 11.2% across 754 paired rows. Two of the three flags sit at or near p95, and FenwickTreeBenchmark.Array_RangeSum(100000) moved +25.0% on a plain array scan in the same run without being in the top three. Exactly the "a flag that does not stand out against the spread is worth re-running before acting on" case the #351 guard prints for.

Nothing outstanding from my side: six Copilot rounds, all findings addressed, the last two clean.

@marius-bughiu
marius-bughiu merged commit 230a36b into main Aug 9, 2026
22 checks passed
@marius-bughiu
marius-bughiu deleted the fix/issue-297-unsigned-hasher-names branch August 9, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UInt32Hasher / UInt64Hasher bare names map to opposite hash strengths (weak fold vs strong finalizer)

2 participants