perf(BitSet): add AggressiveInlining to Flip to match Get/Set (#253) - #277
Conversation
BitSet.Flip(int) does the same bounded single-word mask/mutate work as the two structurally-identical single-bit accessors that bracket it, Get(int) and Set(int, bool), both of which already carry [MethodImpl(MethodImplOptions.AggressiveInlining)]. The missing attribute was an inlining asymmetry rather than a deliberate choice, so Flip now presents the same inlining hint. No behavioural, API, or contract change. Closes #253 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds an inlining hint to BitSet.Flip(int) to make single-bit accessors (Get/Set/Flip) consistent, and documents the change in the changelog.
Changes:
- Add
[MethodImpl(MethodImplOptions.AggressiveInlining)]toBitSet.Flip(int) - Add a changelog entry describing the inlining consistency change
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Celerity/Collections/BitSet.cs | Adds AggressiveInlining attribute to Flip(int) for parity with Get/Set. |
| CHANGELOG.md | Documents the Flip(int) inlining change. |
Trim the [Unreleased] Flip entry down to what changed and why it matters to a caller, dropping the private-field names, bit-shift steps, and JIT rationale the automated reviewer flagged on #277. First example of the changelog brevity convention tracked in #278. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Coverage
Files below 100% line coverage
|
Benchmarks8 regressions Highlights
Collections (376)
Hashers (100)
Same-runner A/B (sharded 6-way): main ( |
What
Adds
[MethodImpl(MethodImplOptions.AggressiveInlining)]toBitSet.Flip(int)so all three single-bit accessors carry the same inlining hint.Flipsits betweenGet(int)andSet(int, bool)insrc/Celerity/Collections/BitSet.csand does the same bounded single-word work they do:(uint)index >= (uint)_lengthbounds guard1UL << (index & WordMask)bit maskref ulong word = ref _words[index >> WordShift]word ref^=) +_version++Both
GetandSetwere already marked[MethodImpl(AggressiveInlining)];Flipwas not. Given the three are structurally identical single-bit accessors, the missing attribute reads as an inlining asymmetry rather than a deliberate choice — a hot-path bit accessor the JIT was free to leave out-of-line while its siblings inlined.Why
Consistency-of-intent in a library that inlines its accessors deliberately. No behavioural, API, or contract change — purely a codegen hint so all three accessors present the same inlining directive.
Testing
dotnet build -c Release— clean (0 warnings, 0 errors)dotnet test --filter FullyQualifiedName~BitSet— 55/55 passingPer the issue's scope note, the change is small enough to apply as a consistency fix matching
Get/Setrather than gate on a dedicated benchmark.Closes #253
🤖 Generated with Claude Code