Skip to content

Latest commit

 

History

History
207 lines (170 loc) · 12.4 KB

File metadata and controls

207 lines (170 loc) · 12.4 KB

BenchmarkDotNet v0.13.12, Windows 10 (10.0.19045.6456/22H2/2022Update)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.403
  [Host]     : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
  DefaultJob : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI


Method Mean Error StdDev Median Ratio RatioSD Completed Work Items Lock Contentions Allocated Alloc Ratio
TickDomain_Distance 0.0798 ns 0.0330 ns 0.0451 ns 0.0728 ns ? ? - - - ?
MicrosecondDomain_Distance 3.0895 ns 0.0955 ns 0.0846 ns 3.0701 ns ? ? - - - ?
MillisecondDomain_Distance 2.7930 ns 0.0631 ns 0.0590 ns 2.7703 ns ? ? - - - ?
SecondDomain_Distance 37.1352 ns 0.6661 ns 0.5905 ns 36.9544 ns ? ? - - - ?
MinuteDomain_Distance 34.9290 ns 0.6961 ns 0.6511 ns 34.9117 ns ? ? - - - ?
HourDomain_Distance 34.1610 ns 0.3908 ns 0.4343 ns 34.2192 ns ? ? - - - ?
DayDomain_Distance 5.7117 ns 0.1339 ns 0.1432 ns 5.6902 ns ? ? - - - ?
MonthDomain_Distance 41.1103 ns 0.3969 ns 0.3713 ns 41.1030 ns ? ? - - - ?
YearDomain_Distance 17.9638 ns 0.2301 ns 0.1796 ns 17.9702 ns ? ? - - - ?
TickDomain_Floor_OnBoundary 0.0081 ns 0.0166 ns 0.0155 ns 0.0000 ns ? ? - - - ?
SecondDomain_Floor_OnBoundary 19.9198 ns 0.2647 ns 0.2600 ns 19.8652 ns ? ? - - - ?
MinuteDomain_Floor_OnBoundary 17.5349 ns 0.2740 ns 0.2288 ns 17.5110 ns ? ? - - - ?
HourDomain_Floor_OnBoundary 16.1906 ns 0.3254 ns 0.5785 ns 16.0293 ns ? ? - - - ?
DayDomain_Floor_OnBoundary 2.3100 ns 0.0265 ns 0.0207 ns 2.3130 ns ? ? - - - ?
MonthDomain_Floor_OnBoundary 9.8138 ns 0.1975 ns 0.2568 ns 9.8082 ns ? ? - - - ?
YearDomain_Floor_OnBoundary 4.4031 ns 0.1269 ns 0.1303 ns 4.3885 ns ? ? - - - ?
SecondDomain_Floor_OffBoundary 18.5965 ns 0.3152 ns 0.3372 ns 18.5699 ns ? ? - - - ?
MinuteDomain_Floor_OffBoundary 19.6727 ns 0.3653 ns 0.3588 ns 19.5768 ns ? ? - - - ?
HourDomain_Floor_OffBoundary 14.7847 ns 0.3338 ns 0.5098 ns 14.6200 ns ? ? - - - ?
DayDomain_Floor_OffBoundary 2.1505 ns 0.0760 ns 0.0711 ns 2.1443 ns ? ? - - - ?
MonthDomain_Floor_OffBoundary 9.4623 ns 0.2126 ns 0.3494 ns 9.4314 ns ? ? - - - ?
SecondDomain_Ceiling_OffBoundary 19.5999 ns 0.1401 ns 0.1094 ns 19.6032 ns ? ? - - - ?
MinuteDomain_Ceiling_OffBoundary 17.8295 ns 0.3812 ns 0.3915 ns 17.6361 ns ? ? - - - ?
HourDomain_Ceiling_OffBoundary 16.5392 ns 0.2708 ns 0.2401 ns 16.5326 ns ? ? - - - ?
DayDomain_Ceiling_OffBoundary 3.3867 ns 0.0738 ns 0.0616 ns 3.3903 ns ? ? - - - ?
MonthDomain_Ceiling_OffBoundary 26.7302 ns 0.2964 ns 0.2772 ns 26.7388 ns ? ? - - - ?
YearDomain_Ceiling_OffBoundary 19.2069 ns 0.3470 ns 0.4511 ns 19.0697 ns ? ? - - - ?
TickDomain_Add 0.3897 ns 0.0151 ns 0.0134 ns 0.3899 ns ? ? - - - ?
SecondDomain_Add 0.5711 ns 0.0235 ns 0.0208 ns 0.5683 ns ? ? - - - ?
HourDomain_Add 0.4524 ns 0.0274 ns 0.0214 ns 0.4449 ns ? ? - - - ?
DayDomain_Add 0.5398 ns 0.0437 ns 0.0912 ns 0.5110 ns ? ? - - - ?
MonthDomain_Add 12.4643 ns 0.2800 ns 0.3112 ns 12.4214 ns ? ? - - - ?
YearDomain_Add 9.7879 ns 0.0687 ns 0.0536 ns 9.8040 ns ? ? - - - ?

Summary

What This Measures

Cross-granularity domain performance—how different DateTime granularities (tick, microsecond, millisecond, second, minute, hour, day, month, year) perform across core operations. Demonstrates how granularity affects computational cost while maintaining O(1) complexity.

Key Performance Insights

⚡ Fine-Grained Domains: Hardware-Speed Operations

  • Tick domain Distance: 0.08 ns (essentially free, pure arithmetic)
  • Microsecond/Millisecond Distance: 2.8-3.1 ns (simple division)
  • Result: Sub-5ns for high-resolution time domains

⏱️ Medium-Grained Domains: Moderate Cost

  • Second domain Distance: 37.1 ns (tick ÷ 10,000,000)
  • Minute domain Distance: 34.9 ns
  • Hour domain Distance: 34.2 ns
  • Pattern: Consistent ~35ns for second/minute/hour

📅 Coarse-Grained Domains: Calendar Arithmetic

  • Day domain Distance: 5.7 ns (simpler, date-based)
  • Month domain Distance: 41.1 ns (variable month lengths)
  • Year domain Distance: 18.0 ns (year arithmetic)

🔧 Floor/Ceiling Operations: Boundary Alignment

  • Tick domain Floor: 0.008 ns (no-op on boundary)
  • Second Floor (on boundary): 19.9 ns
  • Day Floor (on boundary): 2.3 ns
  • Month Floor (on boundary): 9.8 ns
  • Off-boundary overhead: +0-10 ns for forward/backward alignment

➕ Add Operations: Step Advancement

  • Tick domain Add: 0.39 ns (tick arithmetic)
  • Second/Hour/Day Add: 0.45-0.57 ns (TimeSpan operations)
  • Month domain Add: 12.5 ns (AddMonths validation)
  • Year domain Add: 9.8 ns (AddYears validation)

Performance by Granularity

Granularity    Distance (ns)    Floor (ns)    Add (ns)    Complexity
────────────────────────────────────────────────────────────────────
Tick           0.08             0.008         0.39        O(1)
Microsecond    3.09             N/A           N/A         O(1)
Millisecond    2.79             N/A           N/A         O(1)
Second         37.14            19.92         0.57        O(1)
Minute         34.93            17.53         N/A         O(1)
Hour           34.16            16.19         0.45        O(1)
Day            5.71             2.31          0.54        O(1)
Month          41.11            9.81          12.46       O(1)
Year           17.96            4.40          9.79        O(1)

Why Performance Varies by Granularity

Tick (fastest):

  • Pure 64-bit arithmetic
  • No division or calendar logic
  • Hardware-optimized operations

Millisecond/Microsecond:

  • Simple division: ticks / ticksPerUnit
  • Still hardware-accelerated
  • Minimal overhead

Second/Minute/Hour (medium):

  • Larger division factors (10M+ ticks per unit)
  • More CPU cycles for division
  • Still purely arithmetic (O(1))

Day (faster than second!):

  • Uses date arithmetic, not tick arithmetic
  • BCL optimizations for date-only operations
  • No time component overhead

Month/Year (slowest Add):

  • Must handle variable month lengths (28-31 days)
  • Calendar validation (leap years, etc.)
  • Still O(1), just more validation logic

Design Trade-offs (Aligned with README Philosophy)

Why all operations remain O(1):

  • ✅ Every granularity uses arithmetic, not iteration
  • ✅ No loops to count steps
  • ✅ Calendar operations are BCL-optimized
  • ✅ Predictable performance regardless of range size

Why granularity affects cost:

  • Finer granularities: More ticks to process
  • Coarser granularities: More validation logic
  • Calendar granularities (month/year): Variable-length complexity

Why this matters less than you think:

  • Even "slow" operations (Month Distance: 41ns) are incredibly fast
  • All operations < 55 ns
  • Choose granularity for business logic, not performance

Practical Recommendations

All granularities suitable for production:

  • Tick domain: Real-time systems, high-precision timing
  • Millisecond: Event timestamps, logging
  • Second: Typical time calculations
  • Minute/Hour: Scheduling, time windows
  • Day: Date-based calculations
  • Month/Year: Financial periods, contracts

Performance considerations:

  • Tick is fastest but rarely needed (nanosecond precision)
  • Day is surprisingly fast (date arithmetic optimized)
  • Month/Year have validation overhead but still < 50 ns
  • Choose based on requirements, not benchmarks

Real-World Impact

High-Frequency Tick Calculations (1M operations/second):

Tick domain Distance: 0.08 ns × 1M = 80 microseconds/second
Impact: Negligible (0.008% CPU)

Scheduling System (10K hour-based calculations/second):

Hour domain Distance: 34 ns × 10K = 340 microseconds/second
Impact: Negligible (0.034% CPU)

Financial Reporting (1K month-based calculations/batch):

Month domain Add: 12.5 ns × 1K = 12.5 microseconds/batch
Impact: Negligible

Memory Behavior

All domain operations:  0 bytes allocated
All granularities:      Stack-only operations
Domain instances:       Stateless, reusable

Comparison: Granularity vs Performance

Domain Type Best Use Case Distance Cost Add Cost
Tick High-precision timing 0.08 ns 0.39 ns
Second Standard time calculations 37 ns 0.57 ns
Hour Scheduling, time windows 34 ns 0.45 ns
Day Date-based logic (recommended) 5.7 ns 0.54 ns
Month Financial periods 41 ns 12.5 ns

Why This Matters

These benchmarks demonstrate that granularity choice is about business logic, not performance:

  • ✅ All granularities are O(1) guaranteed
  • ✅ All operations < 55 ns (incredibly fast)
  • ✅ Performance differences (0.08 ns vs 41 ns) are negligible in practice
  • ✅ Choose the granularity that matches your domain requirements

Day domain is often the sweet spot: fast (5.7 ns), intuitive, and matches most business logic.

The "expensive" operations (Month/Year Add at 10-12 ns) are still 100× faster than a cache miss—focus on correctness, not micro-optimization.