Skip to content

Commit 5141ff2

Browse files
committed
Refactor benchmark selection
1 parent b85616c commit 5141ff2

6 files changed

Lines changed: 267 additions & 72 deletions

File tree

doc/benchmarks.md

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,147 @@ Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3
239239
| 'Blake3 native parallel' | 10000000 | 653,996.50 ns | 60,925.609 ns | 3,339.538 ns | 0.14 | 0.00 | - | - | - | NA |
240240
| 'Blake3 managed (ext)' | 10000000 | 5,328,655.05 ns | 58,161.314 ns | 3,188.018 ns | 1.10 | 0.00 | - | - | - | NA |
241241
| Blake2Fast | 10000000 | 6,306,882.05 ns | 65,270.984 ns | 3,577.723 ns | 1.31 | 0.00 | - | - | 88 B | NA |
242-
| SHA256 | 10000000 | 2,911,697.86 ns | 313,595.168 ns | 17,189.209 ns | 0.60 | 0.00 | - | - | - | NA |
242+
| SHA256 | 10000000 | 2,911,
243+
244+
## Blake3VsNativeBenchmarks
245+
246+
```
247+
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2)
248+
AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
249+
.NET SDK 10.0.302
250+
[Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
251+
ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
252+
253+
Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3
254+
```
255+
256+
| Method | N | Mean | Error | StdDev | Ratio | Code Size | Allocated | Alloc Ratio |
257+
|----------------- |--------- |--------------:|--------------:|-------------:|------:|----------:|----------:|------------:|
258+
| 'Blake3 default' | 4 | 82.12 ns | 2.671 ns | 0.146 ns | 1.00 | 3,218 B | - | NA |
259+
| 'Blake3 native' | 4 | 75.27 ns | 0.196 ns | 0.011 ns | 0.92 | 355 B | - | NA |
260+
| | | | | | | | | |
261+
| 'Blake3 default' | 100 | 123.12 ns | 0.984 ns | 0.054 ns | 1.00 | 3,211 B | - | NA |
262+
| 'Blake3 native' | 100 | 138.03 ns | 2.187 ns | 0.120 ns | 1.12 | 355 B | - | NA |
263+
| | | | | | | | | |
264+
| 'Blake3 default' | 1000 | 1,114.55 ns | 3.604 ns | 0.198 ns | 1.00 | 3,211 B | - | NA |
265+
| 'Blake3 native' | 1000 | 992.50 ns | 9.308 ns | 0.510 ns | 0.89 | 355 B | - | NA |
266+
| | | | | | | | | |
267+
| 'Blake3 default' | 10000 | 3,612.77 ns | 115.985 ns | 6.358 ns | 1.00 | 7,350 B | - | NA |
268+
| 'Blake3 native' | 10000 | 3,098.95 ns | 20.440 ns | 1.120 ns | 0.86 | 360 B | - | NA |
269+
| | | | | | | | | |
270+
| 'Blake3 default' | 65536 | 6,030.67 ns | 17.941 ns | 0.983 ns | 1.00 | 8,169 B | - | NA |
271+
| 'Blake3 native' | 65536 | 4,987.99 ns | 86.206 ns | 4.725 ns | 0.83 | 360 B | - | NA |
272+
| | | | | | | | | |
273+
| 'Blake3 default' | 100000 | 10,905.14 ns | 320.218 ns | 17.552 ns | 1.00 | 8,494 B | - | NA |
274+
| 'Blake3 native' | 100000 | 9,225.64 ns | 171.406 ns | 9.395 ns | 0.85 | 360 B | - | NA |
275+
| | | | | | | | | |
276+
| 'Blake3 default' | 131072 | 11,754.00 ns | 25.263 ns | 1.385 ns | 1.00 | 8,155 B | - | NA |
277+
| 'Blake3 native' | 131072 | 9,745.71 ns | 164.301 ns | 9.006 ns | 0.83 | 360 B | - | NA |
278+
| | | | | | | | | |
279+
| 'Blake3 default' | 262144 | 23,587.73 ns | 852.524 ns | 46.730 ns | 1.00 | 8,155 B | - | NA |
280+
| 'Blake3 native' | 262144 | 19,280.80 ns | 237.858 ns | 13.038 ns | 0.82 | 360 B | - | NA |
281+
| | | | | | | | | |
282+
| 'Blake3 default' | 524288 | 46,399.06 ns | 2,031.634 ns | 111.361 ns | 1.00 | 8,155 B | - | NA |
283+
| 'Blake3 native' | 524288 | 38,418.34 ns | 183.719 ns | 10.070 ns | 0.83 | 360 B | - | NA |
284+
| | | | | | | | | |
285+
| 'Blake3 default' | 1000000 | 88,234.66 ns | 2,110.065 ns | 115.660 ns | 1.00 | 8,485 B | - | NA |
286+
| 'Blake3 native' | 1000000 | 75,019.60 ns | 429.557 ns | 23.545 ns | 0.85 | 360 B | - | NA |
287+
| | | | | | | | | |
288+
| 'Blake3 default' | 10000000 | 907,587.73 ns | 45,363.456 ns | 2,486.524 ns | 1.00 | 8,441 B | - | NA |
289+
| 'Blake3 native' | 10000000 | 756,075.81 ns | 41,412.564 ns | 2,269.962 ns | 0.83 | 360 B | - | NA |
290+
291+
292+
## ExternalHashBenchmarks
293+
294+
295+
```
296+
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2)
297+
AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
298+
.NET SDK 10.0.302
299+
[Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
300+
ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
301+
302+
Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3
303+
```
304+
305+
| Method | N | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Code Size | Allocated | Alloc Ratio |
306+
|----------------------- |--------- |----------------:|--------------:|-------------:|------:|--------:|-------:|----------:|----------:|------------:|
307+
| 'Blake3 default' | 4 | 82.42 ns | 11.776 ns | 0.645 ns | 1.00 | 0.01 | - | 3,218 B | - | NA |
308+
| 'Blake3 managed (ext)' | 4 | 86.94 ns | 0.212 ns | 0.012 ns | 1.05 | 0.01 | - | 3,745 B | - | NA |
309+
| Blake2Fast | 4 | 133.42 ns | 0.486 ns | 0.027 ns | 1.62 | 0.01 | 0.0052 | 5,453 B | 88 B | NA |
310+
| SHA256 | 4 | 103.44 ns | 4.587 ns | 0.251 ns | 1.25 | 0.01 | - | 342 B | - | NA |
311+
| | | | | | | | | | | |
312+
| 'Blake3 default' | 100 | 123.47 ns | 1.800 ns | 0.099 ns | 1.00 | 0.00 | - | 3,211 B | - | NA |
313+
| 'Blake3 managed (ext)' | 100 | 150.45 ns | 1.767 ns | 0.097 ns | 1.22 | 0.00 | - | 3,992 B | - | NA |
314+
| Blake2Fast | 100 | 134.52 ns | 10.890 ns | 0.597 ns | 1.09 | 0.00 | 0.0052 | 5,450 B | 88 B | NA |
315+
| SHA256 | 100 | 126.18 ns | 5.356 ns | 0.294 ns | 1.02 | 0.00 | - | 342 B | - | NA |
316+
| | | | | | | | | | | |
317+
| 'Blake3 default' | 1000 | 1,115.35 ns | 3.225 ns | 0.177 ns | 1.00 | 0.00 | - | 3,211 B | - | NA |
318+
| 'Blake3 managed (ext)' | 1000 | 1,053.13 ns | 15.556 ns | 0.853 ns | 0.94 | 0.00 | - | 3,992 B | - | NA |
319+
| Blake2Fast | 1000 | 949.12 ns | 4.116 ns | 0.226 ns | 0.85 | 0.00 | 0.0048 | 5,546 B | 88 B | NA |
320+
| SHA256 | 1000 | 444.94 ns | 8.808 ns | 0.483 ns | 0.40 | 0.00 | - | 342 B | - | NA |
321+
| | | | | | | | | | | |
322+
| 'Blake3 default' | 10000 | 3,606.93 ns | 20.725 ns | 1.136 ns | 1.00 | 0.00 | - | 7,354 B | - | NA |
323+
| 'Blake3 managed (ext)' | 10000 | 3,834.32 ns | 66.911 ns | 3.668 ns | 1.06 | 0.00 | - | 18,213 B | 56 B | NA |
324+
| Blake2Fast | 10000 | 9,242.27 ns | 247.965 ns | 13.592 ns | 2.56 | 0.00 | - | 5,549 B | 88 B | NA |
325+
| SHA256 | 10000 | 3,673.16 ns | 141.781 ns | 7.771 ns | 1.02 | 0.00 | - | 342 B | - | NA |
326+
| | | | | | | | | | | |
327+
| 'Blake3 default' | 65536 | 6,025.40 ns | 267.785 ns | 14.678 ns | 1.00 | 0.00 | - | 8,169 B | - | NA |
328+
| 'Blake3 managed (ext)' | 65536 | 14,552.86 ns | 262.955 ns | 14.413 ns | 2.42 | 0.01 | - | 18,114 B | 56 B | NA |
329+
| Blake2Fast | 65536 | 59,733.70 ns | 80.460 ns | 4.410 ns | 9.91 | 0.02 | - | 5,827 B | 88 B | NA |
330+
| SHA256 | 65536 | 23,581.89 ns | 748.634 ns | 41.035 ns | 3.91 | 0.01 | - | 342 B | - | NA |
331+
| | | | | | | | | | | |
332+
| 'Blake3 default' | 100000 | 10,907.97 ns | 582.644 ns | 31.937 ns | 1.00 | 0.00 | - | 8,456 B | - | NA |
333+
| 'Blake3 managed (ext)' | 100000 | 14,958.62 ns | 235.925 ns | 12.932 ns | 1.37 | 0.00 | 0.1221 | 30,276 B | 2231 B | NA |
334+
| Blake2Fast | 100000 | 91,314.10 ns | 3,061.176 ns | 167.793 ns | 8.37 | 0.03 | - | 5,549 B | 88 B | NA |
335+
| SHA256 | 100000 | 35,867.08 ns | 1,181.185 ns | 64.745 ns | 3.29 | 0.01 | - | 342 B | - | NA |
336+
| | | | | | | | | | | |
337+
| 'Blake3 default' | 131072 | 11,538.65 ns | 34.346 ns | 1.883 ns | 1.00 | 0.00 | - | 8,155 B | - | NA |
338+
| 'Blake3 managed (ext)' | 131072 | 17,473.52 ns | 625.486 ns | 34.285 ns | 1.51 | 0.00 | 0.1221 | 30,044 B | 2508 B | NA |
339+
| Blake2Fast | 131072 | 119,413.87 ns | 413.862 ns | 22.685 ns | 10.35 | 0.00 | - | 5,827 B | 88 B | NA |
340+
| SHA256 | 131072 | 46,945.24 ns | 559.570 ns | 30.672 ns | 4.07 | 0.00 | - | 342 B | - | NA |
341+
| | | | | | | | | | | |
342+
| 'Blake3 default' | 262144 | 23,386.06 ns | 544.747 ns | 29.859 ns | 1.00 | 0.00 | - | 8,155 B | - | NA |
343+
| 'Blake3 managed (ext)' | 262144 | 18,825.93 ns | 745.672 ns | 40.873 ns | 0.81 | 0.00 | 0.1526 | 30,020 B | 2858 B | NA |
344+
| Blake2Fast | 262144 | 239,922.34 ns | 2,700.268 ns | 148.011 ns | 10.26 | 0.01 | - | 5,826 B | 88 B | NA |
345+
| SHA256 | 262144 | 93,802.67 ns | 257.119 ns | 14.094 ns | 4.01 | 0.00 | - | 342 B | - | NA |
346+
| | | | | | | | | | | |
347+
| 'Blake3 default' | 524288 | 46,882.88 ns | 3,506.974 ns | 192.229 ns | 1.00 | 0.01 | - | 8,155 B | - | NA |
348+
| 'Blake3 managed (ext)' | 524288 | 27,097.21 ns | 941.849 ns | 51.626 ns | 0.58 | 0.00 | 0.2136 | 30,033 B | 3699 B | NA |
349+
| Blake2Fast | 524288 | 480,848.50 ns | 48,825.934 ns | 2,676.314 ns | 10.26 | 0.06 | - | 5,823 B | 88 B | NA |
350+
| SHA256 | 524288 | 190,418.43 ns | 44,029.824 ns | 2,413.423 ns | 4.06 | 0.05 | - | 342 B | - | NA |
351+
| | | | | | | | | | | |
352+
| 'Blake3 default' | 1000000 | 91,670.84 ns | 31,592.943 ns | 1,731.716 ns | 1.00 | 0.02 | - | 8,485 B | - | NA |
353+
| 'Blake3 managed (ext)' | 1000000 | 35,480.01 ns | 64,008.083 ns | 3,508.499 ns | 0.39 | 0.03 | 0.2441 | 29,502 B | 4253 B | NA |
354+
| Blake2Fast | 1000000 | 913,685.16 ns | 30,384.972 ns | 1,665.503 ns | 9.97 | 0.16 | - | 5,539 B | 88 B | NA |
355+
| SHA256 | 1000000 | 358,664.79 ns | 10,127.695 ns | 555.133 ns | 3.91 | 0.06 | - | 342 B | - | NA |
356+
| | | | | | | | | | | |
357+
| 'Blake3 default' | 10000000 | 925,091.31 ns | 71,865.863 ns | 3,939.210 ns | 1.00 | 0.01 | - | 8,441 B | - | NA |
358+
| 'Blake3 managed (ext)' | 10000000 | 221,220.17 ns | 6,563.852 ns | 359.787 ns | 0.24 | 0.00 | 0.2441 | 37,399 B | 7923 B | NA |
359+
| Blake2Fast | 10000000 | 9,159,290.62 ns | 32,710.881 ns | 1,792.994 ns | 9.90 | 0.04 | - | 5,823 B | 88 B | NA |
360+
| SHA256 | 10000000 | 3,576,552.21 ns | 10,767.420 ns | 590.199 ns | 3.87 | 0.01 | - | 342 B | - | NA |
361+
362+
363+
## Blake3ParallelBenchmarks
364+
365+
```
366+
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2)
367+
AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
368+
.NET SDK 10.0.302
369+
[Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
370+
ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
371+
372+
Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3
373+
```
374+
375+
| Method | N | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
376+
|------------------------- |--------- |----------:|----------:|---------:|------:|--------:|-------:|----------:|------------:|
377+
| 'Blake3 parallel' | 524288 | 50.56 us | 14.678 us | 0.805 us | 1.00 | 0.02 | 0.2441 | 4197 B | 1.00 |
378+
| 'Blake3 native parallel' | 524288 | 17.23 us | 0.411 us | 0.023 us | 0.34 | 0.00 | - | - | 0.00 |
379+
| | | | | | | | | | |
380+
| 'Blake3 parallel' | 1000000 | 26.95 us | 3.921 us | 0.215 us | 1.00 | 0.01 | 0.4272 | 7072 B | 1.00 |
381+
| 'Blake3 native parallel' | 1000000 | 184.98 us | 46.628 us | 2.556 us | 6.86 | 0.09 | - | - | 0.00 |
382+
| | | | | | | | | | |
383+
| 'Blake3 parallel' | 10000000 | 207.25 us | 30.229 us | 1.657 us | 1.00 | 0.01 | 1.4648 | 25776 B | 1.00 |
384+
| 'Blake3 native parallel' | 10000000 | 116.22 us | 14.228 us | 0.780 us | 0.56 | 0.01 | - | - | 0.00 |
385+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using BenchmarkDotNet.Attributes;
2+
using System;
3+
4+
namespace Blake3.Benchmarks
5+
{
6+
public abstract class Blake3BenchmarkBase
7+
{
8+
protected byte[] Data { get; private set; } = Array.Empty<byte>();
9+
10+
public abstract int N { get; set; }
11+
12+
[GlobalSetup]
13+
public void Setup()
14+
{
15+
Data = new byte[N];
16+
new Random(42).NextBytes(Data);
17+
}
18+
}
19+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
extern alias NativeBlake3;
2+
3+
using BenchmarkDotNet.Attributes;
4+
using System.Runtime.InteropServices;
5+
using NativeHasher = NativeBlake3::Blake3.Hasher;
6+
7+
namespace Blake3.Benchmarks
8+
{
9+
[RPlotExporter]
10+
public class Blake3ParallelBenchmarks : Blake3BenchmarkBase
11+
{
12+
[Params(524288, 1000000, 10000000)]
13+
public override int N { get; set; }
14+
15+
[Benchmark(Baseline = true, Description = "Blake3 parallel")]
16+
public uint RunBlake3Parallel()
17+
{
18+
using var hasher = Hasher.New();
19+
hasher.UpdateWithJoin(Data);
20+
return MemoryMarshal.Cast<byte, uint>(hasher.Finalize().AsSpan())[0];
21+
}
22+
23+
[Benchmark(Description = "Blake3 native parallel")]
24+
public uint RunBlake3NativeParallel()
25+
{
26+
using var hasher = NativeHasher.New();
27+
hasher.UpdateWithJoin(Data);
28+
return MemoryMarshal.Cast<byte, uint>(hasher.Finalize().AsSpan())[0];
29+
}
30+
}
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
extern alias NativeBlake3;
2+
3+
using BenchmarkDotNet.Attributes;
4+
using System.Runtime.InteropServices;
5+
using NativeHasher = NativeBlake3::Blake3.Hasher;
6+
7+
namespace Blake3.Benchmarks
8+
{
9+
[RPlotExporter]
10+
public class Blake3VsNativeBenchmarks : Blake3BenchmarkBase
11+
{
12+
[Params(4, 100, 1000, 10000, 65536, 100000, 131072, 262144, 524288, 1000000, 10000000)]
13+
public override int N { get; set; }
14+
15+
[Benchmark(Baseline = true, Description = "Blake3 default")]
16+
public uint RunBlake3()
17+
{
18+
return MemoryMarshal.Cast<byte, uint>(Hasher.Hash(Data).AsSpan())[0];
19+
}
20+
21+
[Benchmark(Description = "Blake3 native")]
22+
public uint RunBlake3Native()
23+
{
24+
return MemoryMarshal.Cast<byte, uint>(NativeHasher.Hash(Data).AsSpan())[0];
25+
}
26+
}
27+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using BenchmarkDotNet.Attributes;
2+
using Blake2Fast;
3+
using System;
4+
using System.Runtime.InteropServices;
5+
using ManagedHasher = Blake3.Managed.Hasher;
6+
7+
namespace Blake3.Benchmarks
8+
{
9+
[RPlotExporter]
10+
public class ExternalHashBenchmarks : Blake3BenchmarkBase
11+
{
12+
[Params(4, 100, 1000, 10000, 65536, 100000, 131072, 262144, 524288, 1000000, 10000000)]
13+
public override int N { get; set; }
14+
15+
[Benchmark(Baseline = true, Description = "Blake3 default")]
16+
public uint RunBlake3()
17+
{
18+
return MemoryMarshal.Cast<byte, uint>(Hasher.Hash(Data).AsSpan())[0];
19+
}
20+
21+
[Benchmark(Description = "Blake3 managed (ext)")]
22+
public uint RunBlake3Managed()
23+
{
24+
return MemoryMarshal.Cast<byte, uint>(ManagedHasher.Hash(Data).AsSpan())[0];
25+
}
26+
27+
[Benchmark(Description = "Blake2Fast")]
28+
public uint RunBlake2Fast()
29+
{
30+
return MemoryMarshal.Cast<byte, uint>(Blake2b.ComputeHash(Data))[0];
31+
}
32+
33+
[Benchmark(Description = "SHA256")]
34+
public uint RunSHA256()
35+
{
36+
Span<byte> hash = stackalloc byte[32];
37+
System.Security.Cryptography.SHA256.HashData(Data, hash);
38+
return MemoryMarshal.Cast<byte, uint>(hash)[0];
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)