Commit 663addb
Simplify TryParseFormatO fractional-seconds handling (#129005)
### Simplify `TryParseFormatO` fractional-seconds handling
The `"O"` (ISO 8601 round-trip) format always has exactly 7
fractional-second digits, which matches `DateTime`'s tick precision
(`TimeSpan.TicksPerSecond == 10_000_000`). The integer formed by those
seven digits is therefore *exactly* the sub-second tick count, so we can
pass it straight to `TryAddTicks` instead of routing it through a
`double` divide / multiply / `Math.Round` round-trip.
The change is bit-exact: every one of the 10M possible 7-digit values
produces the same tick count as before (verified by brute-force).
### Tests
Existing `System.Tests.DateTimeTests` (1378 tests) and
`System.Tests.DateTimeOffsetTests` (737 tests, 2 platform-skipped) pass
against a CoreLib built with the change.
### Microbenchmark
Side benefit: a small (~6%) speedup on `Perf_DateTime.ParseO` on R2R'd
CoreLib.
Benchmarks used (unchanged, from
[`dotnet/performance`](https://github.com/dotnet/performance)):
-
[`Perf_DateTime.ParseO`](https://github.com/dotnet/performance/blob/643b4e7022538b58bfc274312730a6116dc91c55/src/benchmarks/micro/libraries/System.Runtime/Perf.DateTime.cs#L52)
— target
-
[`Perf_DateTime.ParseR`](https://github.com/dotnet/performance/blob/643b4e7022538b58bfc274312730a6116dc91c55/src/benchmarks/micro/libraries/System.Runtime/Perf.DateTime.cs#L49)
— unchanged control
Run with BenchmarkDotNet `Job.Default`, same-process A/B (both
`--coreRun`s passed in one invocation so process-startup, ASLR, and
thermal effects don't bias the comparison), affinity-pinned to a single
P-core:
```
dotnet run -c Release -f net11.0 --project src/benchmarks/micro/MicroBenchmarks.csproj -- \
--filter "System.Tests.Perf_DateTime.ParseO" "System.Tests.Perf_DateTime.ParseR" \
--coreRun <baseline-testhost>\CoreRun.exe <patched-testhost>\CoreRun.exe \
--affinity 1
```
Environment: Windows 11, Intel Core i9-14900K (P-core 0 pinned), .NET
11.0 R2R'd `System.Private.CoreLib` (Release), BenchmarkDotNet
v0.16.0-nightly.
| Method | Job | Mean | Error | StdDev | Ratio | RatioSD |
|------- |-----------
|---------:|---------:|---------:|------:|--------:|
| ParseR | baseline | 11.42 ns | 0.168 ns | 0.149 ns | 1.00 | 0.00 |
| ParseR | patched | 11.41 ns | 0.163 ns | 0.144 ns | 1.00 | 0.02 |
| | | | | | | |
| ParseO | baseline | 11.87 ns | 0.198 ns | 0.175 ns | 1.00 | 0.00 |
| ParseO | patched | 11.14 ns | 0.125 ns | 0.111 ns | 0.94 | 0.02 |
`ParseR` (control) is identical between the two binaries, confirming the
harness is stable; `ParseO` improves ~6% (~0.73 ns/call).
> [!NOTE]
> This PR was prepared with the assistance of GitHub Copilot.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent e99ab10 commit 663addb
1 file changed
Lines changed: 8 additions & 4 deletions
Lines changed: 8 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5171 | 5171 | | |
5172 | 5172 | | |
5173 | 5173 | | |
5174 | | - | |
| 5174 | + | |
| 5175 | + | |
| 5176 | + | |
| 5177 | + | |
| 5178 | + | |
5175 | 5179 | | |
5176 | 5180 | | |
5177 | 5181 | | |
| |||
5187 | 5191 | | |
5188 | 5192 | | |
5189 | 5193 | | |
5190 | | - | |
| 5194 | + | |
5191 | 5195 | | |
5192 | 5196 | | |
5193 | 5197 | | |
5194 | 5198 | | |
5195 | | - | |
| 5199 | + | |
5196 | 5200 | | |
5197 | 5201 | | |
5198 | 5202 | | |
| |||
5204 | 5208 | | |
5205 | 5209 | | |
5206 | 5210 | | |
5207 | | - | |
| 5211 | + | |
5208 | 5212 | | |
5209 | 5213 | | |
5210 | 5214 | | |
| |||
0 commit comments