BENCHMARKS · PARSING
Integers and timestamps: Parse, TryParse, and byte-level variants. Suite and raw reports: github.com/gdhami-net/dotnet-benchmarks.
ParseIntegers
Parse 10,000 integers: Parse vs TryParse vs Utf8Parser straight off bytes.
TAKEAWAY TryParse costs nothing over Parse - use it everywhere input can be wrong. Parsing straight from UTF-8 bytes skips the string entirely when you own the wire format.
In this run: Utf8Parser_bytes is fastest — 1.9× faster than the baseline.
In this run: Utf8Parser_bytes is fastest — 1.9× faster than the baseline.
RESULTS
| method | net9.0 | net10.0 | ratio | allocated | Δ net10.0 |
|---|---|---|---|---|---|
| Int_parse baseline | 43.7 µs ±489 ns | 48.1 µs ±588 ns | 1.00× | — | +10% |
| Int_tryparse | 43.0 µs ±174 ns | 44.2 µs ±275 ns | 0.92× | — | +3% |
| Utf8Parser_bytes | 27.4 µs ±505 ns | 25.5 µs ±106 ns | 0.53× | — | -7% |
RATIO VS BASELINE · net10.0
THE LEDGER · SAME WORKLOAD ACROSS RELEASES (LOG)
Int_parseInt_tryparseUtf8Parser_bytes
THE CODE BEING MEASURED
Int_parse — what this measures
int.Parse — throws on bad input, fine on good input.
[Benchmark (Baseline)]
public long Int_parse()
{
long sum = 0;
foreach (var s in _strings) sum += int.Parse(s);
return sum;
}Int_tryparse — what this measures
int.TryParse — the defensive twin.
[Benchmark]
public long Int_tryparse()
{
long sum = 0;
foreach (var s in _strings)
if (int.TryParse(s, out var v)) sum += v;
return sum;
}Utf8Parser_bytes — what this measures
Utf8Parser over raw bytes — no string in sight.
[Benchmark]
public long Utf8Parser_bytes()
{
long sum = 0;
foreach (var b in _utf8)
if (Utf8Parser.TryParse(b, out int v, out _)) sum += v;
return sum;
}ParseTimestamps
Parse 10,000 timestamps: culture-hunting DateTime.Parse vs ParseExact vs TryParseExact.
TAKEAWAY If you know the format, say so: ParseExact skips the format-guessing dance. DateTime.Parse is for genuinely unknown input, not for your own logs.
In this run: DateTime_parse is fastest (it is the baseline).
In this run: DateTime_parse is fastest (it is the baseline).
RESULTS
| method | net9.0 | net10.0 | ratio | allocated | Δ net10.0 |
|---|---|---|---|---|---|
| DateTime_parse baseline | 757.9 µs ±5.7 µs | 739.2 µs ±4.0 µs | 1.00× | — | -2% |
| DateTime_parseexact | 928.5 µs ±1.9 µs | 989.2 µs ±31.3 µs | 1.34× | — | +7% |
| DateTime_tryparseexact | 950.3 µs ±16.4 µs | 1.00 ms ±9.6 µs | 1.36× | — | +6% |
RATIO VS BASELINE · net10.0
THE LEDGER · SAME WORKLOAD ACROSS RELEASES (LOG)
DateTime_parseDateTime_parseexactDateTime_tryparseexact
THE CODE BEING MEASURED
DateTime_parse — what this measures
DateTime.Parse — flexible, and it pays for the flexibility.
[Benchmark (Baseline)]
public long DateTime_parse()
{
long ticks = 0;
foreach (var s in _stamps) ticks += DateTime.Parse(s, CultureInfo.InvariantCulture).Ticks;
return ticks;
}DateTime_parseexact — what this measures
ParseExact with a known format.
[Benchmark]
public long DateTime_parseexact()
{
long ticks = 0;
foreach (var s in _stamps) ticks += DateTime.ParseExact(s, Format, CultureInfo.InvariantCulture).Ticks;
return ticks;
}DateTime_tryparseexact — what this measures
TryParseExact — exact format, no exceptions on the unhappy path.
[Benchmark]
public long DateTime_tryparseexact()
{
long ticks = 0;
foreach (var s in _stamps)
if (DateTime.TryParseExact(s, Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var d))
ticks += d.Ticks;
return ticks;
}