Skip to content

Commit 7720d03

Browse files
leecampbell-codeagentLeeCampbell
authored andcommitted
plan(#161): apply brief review feedback
1 parent 7e84d97 commit 7720d03

2 files changed

Lines changed: 10 additions & 136 deletions

File tree

plan/planning/brief-review.md

Lines changed: 0 additions & 82 deletions
This file was deleted.

plan/planning/brief.md

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,28 @@
44

55
Remove `netstandard2.0` from the main library's `<TargetFrameworks>`, retaining only `net10.0;net9.0;net8.0`.
66
This eliminates all conditional compilation guards that existed solely to support the older target, simplifies `Bitwise.cs` to use `BitOperations.LeadingZeroCount` unconditionally, and cleans up a branching code path in `HistogramLogReader.cs`.
7+
The three per-framework Release `PropertyGroup` conditions in the csproj are collapsed into a single unconditional `PropertyGroup` as part of this change.
78
The spec file `build-system.md` must be updated to reflect the new target list.
89

910
Previous NuGet releases remain available on NuGet.org for consumers on .NET Framework or older runtimes.
1011

1112
## Category
1213

13-
`performance`
14+
`chore`
1415

15-
Performance is a primary motivation: the netstandard2.0 code path uses a slow, lookup-table-based `LeadingZeroCount` rather than the `BitOperations` hardware intrinsic.
16-
This change also delivers simplification and a reduction in build artefacts, but the performance impact on a hot instrumentation path is the key driver.
16+
This is a maintenance and simplification task.
17+
The hardware-intrinsic `LeadingZeroCount` path (`#if NET5_0_OR_GREATER`) is already compiled in for all net8.0+ builds; removing the fallback does not change the compiled output for any net8.0, net9.0, or net10.0 consumer.
18+
No performance improvement is delivered to existing net8.0+ consumers — the change reduces build artefacts, removes dead code, and simplifies the codebase.
1719

1820
## Affected Files (confirmed by exploration)
1921

2022
| File | Change required |
2123
|------|----------------|
22-
| `HdrHistogram/HdrHistogram.csproj` | Remove `netstandard2.0` from `<TargetFrameworks>` (line 4); delete the netstandard2.0 `PropertyGroup` condition (lines 36-39) |
24+
| `HdrHistogram/HdrHistogram.csproj` | Remove `netstandard2.0` from `<TargetFrameworks>` (line 4); delete the netstandard2.0 `PropertyGroup` condition (lines 36-39); collapse the three per-framework Release `PropertyGroup` conditions (lines 24-34) into a single `Condition="'$(Configuration)' == 'Release'"` block |
2325
| `HdrHistogram/Utilities/Bitwise.cs` | Remove `#if NET5_0_OR_GREATER` guards (lines 25-29, 32-44); inline `IntrinsicNumberOfLeadingZeros` body directly into `NumberOfLeadingZeros`; delete the entire `Bitwise.Imperative` class (lines 55-109) |
2426
| `HdrHistogram/HistogramLogReader.cs` | Remove `#if NETSTANDARD2_0` block in `IsComment()` (lines 241-248); keep the `char` overload unconditionally |
2527
| `spec/tech-standards/build-system.md` | Remove `netstandard2.0` from the TargetFrameworks code block (line 25) and from the target table (line 33) |
28+
| `HdrHistogram.Benchmarking/LeadingZeroCount/LeadingZeroCountBenchmarkBase.cs` | Remove the `ImperativeImplementation` benchmark method (references deleted `Bitwise.Imperative` class) |
2629

2730
No other files in the codebase contain `#if NETSTANDARD` or `#if NET5_0_OR_GREATER` blocks.
2831
Unit-test and benchmarking projects already target `net10.0;net9.0;net8.0` only — no changes needed there.
@@ -34,6 +37,8 @@ Unit-test and benchmarking projects already target `net10.0;net9.0;net8.0` only
3437
- [ ] `Bitwise.Imperative` class is fully removed
3538
- [ ] `Bitwise.NumberOfLeadingZeros` calls `System.Numerics.BitOperations.LeadingZeroCount` unconditionally
3639
- [ ] `HistogramLogReader.IsComment` uses `line.StartsWith('#')` (char overload) unconditionally
40+
- [ ] The three per-framework Release `PropertyGroup` conditions are collapsed into a single `Condition="'$(Configuration)' == 'Release'"` block
41+
- [ ] `LeadingZeroCountBenchmarkBase.cs` no longer references `Bitwise.Imperative`; the benchmarking project compiles cleanly
3742
- [ ] All unit tests pass on net8.0, net9.0, and net10.0
3843
- [ ] `spec/tech-standards/build-system.md` no longer references `netstandard2.0`
3944

@@ -58,63 +63,14 @@ This is low-risk but provides a regression anchor if `Bitwise.cs` is touched aga
5863

5964
There is no need to add tests for `IsComment` — it is a private static helper with trivial logic.
6065

61-
## Benchmark Strategy
62-
63-
### Why benchmarks are required
64-
65-
This is a `performance` category issue.
66-
The stated motivation is that the netstandard2.0 fallback path is slower.
67-
Benchmarks must confirm that the hardware-intrinsic path is indeed faster and that the improvement is observable at both micro and end-to-end level.
68-
69-
### Existing relevant benchmarks
70-
71-
`HdrHistogram.Benchmarking/LeadingZeroCount/` already contains benchmarks for this exact area:
72-
73-
- `LeadingZeroCountBenchmarkBase.cs` — benchmarks `Bitwise.NumberOfLeadingZeros()` (intrinsic path, line 119) and `Bitwise.Imperative.NumberOfLeadingZeros()` (fallback, line 130)
74-
75-
These benchmarks were written to compare the two implementations.
76-
After `Bitwise.Imperative` is deleted, the `ImperativeImplementation` benchmark method must be removed or updated.
77-
78-
### Benchmark development plan
79-
80-
**Phase 1 — Baseline (before any code changes):**
81-
82-
1. Run the existing `LeadingZeroCount` benchmarks in Release mode against the current code to capture baseline metrics for both the intrinsic and imperative paths.
83-
Record: Mean, StdDev, Allocated, Op/s.
84-
2. If an end-to-end benchmark for `RecordValue` throughput exists (check `Recording/`), run it too.
85-
86-
**Phase 2 — Implementation:**
87-
88-
3. Apply the changes described above.
89-
4. Remove the `ImperativeImplementation` benchmark method from `LeadingZeroCountBenchmarkBase.cs` (it references the deleted class).
90-
5. Update `Program.cs` `BenchmarkSwitcher` if the benchmark class is renamed.
91-
92-
**Phase 3 — Validation:**
93-
94-
6. Re-run the `LeadingZeroCount` micro-benchmarks and any `Recording` end-to-end benchmarks.
95-
7. Produce a before/after table (Mean, Allocated, Op/s) and include it in the PR description.
96-
97-
**Metrics that matter:**
98-
99-
| Metric | Relevance |
100-
|--------|-----------|
101-
| Mean throughput (Op/s) | Primary — shows intrinsic is faster than the lookup table |
102-
| Allocated (bytes) | Secondary — both paths should allocate nothing; confirms no regression |
103-
| GC Gen0/Gen1 collections | Sanity check — should remain zero for both paths |
104-
105-
A micro-benchmark improvement in `LeadingZeroCount` that does not translate to observable improvement in `RecordValue` throughput is expected (the intrinsic is already used on net8.0+), but the benchmark result still validates correctness and code simplification.
106-
10766
## Risks and Open Questions
10867

10968
1. **Benchmark class references `Bitwise.Imperative`** — deleting the class will break the `ImperativeImplementation` benchmark at compile time.
110-
The benchmark must be updated in the same PR.
69+
The benchmark must be updated in the same PR (listed in Affected Files above).
11170

11271
2. **NuGet package surface** — removing a target framework is a breaking change for consumers on netstandard2.0.
11372
This is explicitly accepted: "Previous NuGet releases will remain available."
11473
The PR description should note this prominently and suggest a major-version bump or release notes entry.
11574

11675
3. **No other conditional compilation found** — the grep over the codebase confirmed only two files contain the relevant `#if` blocks.
11776
Low risk of missing anything.
118-
119-
4. **Documentation file `PropertyGroup` condition** — the existing per-framework Release `PropertyGroup` conditions for net8.0, net9.0, net10.0 (lines 24-34 of the csproj) can be collapsed into a single unconditional `PropertyGroup Condition="'$(Configuration)' == 'Release'"` as shown in `build-system.md`.
120-
This is a tidy-up that is in scope but should be confirmed with the implementer.

0 commit comments

Comments
 (0)