@@ -19,8 +19,11 @@ const Hash = struct {
19
19
has_iterative_api : bool = true ,
20
20
has_crypto_api : bool = false ,
21
21
has_anytype_api : ? []const comptime_int = null ,
22
+ /// `final` value should be read from this field.
23
+ has_struct_api : ? []const u8 = null ,
22
24
init_u8s : ? []const u8 = null ,
23
25
init_u64 : ? u64 = null ,
26
+ init_default : bool = false ,
24
27
};
25
28
26
29
const hashes = [_ ]Hash {
@@ -54,6 +57,8 @@ const hashes = [_]Hash{
54
57
Hash {
55
58
.ty = hash .Adler32 ,
56
59
.name = "adler32" ,
60
+ .has_struct_api = "adler" ,
61
+ .init_default = true ,
57
62
},
58
63
Hash {
59
64
.ty = hash .crc .Crc32 ,
@@ -112,21 +117,29 @@ pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Alloc
112
117
113
118
const block_count = bytes / block_size ;
114
119
115
- var h = blk : {
120
+ var h : H.ty = blk : {
116
121
if (H .init_u8s ) | init | {
117
- break :blk H . ty .init (init [0.. H .ty .key_length ]);
122
+ break :blk .init (init [0.. H .ty .key_length ]);
118
123
}
119
124
if (H .init_u64 ) | init | {
120
- break :blk H . ty .init (init );
125
+ break :blk .init (init );
121
126
}
122
- break :blk H .ty .init ();
127
+ if (H .init_default ) {
128
+ break :blk .{};
129
+ }
130
+ break :blk .init ();
123
131
};
124
132
125
133
var timer = try Timer .start ();
126
134
for (0.. block_count ) | i | {
127
135
h .update (blocks [i * block_size .. ][0.. block_size ]);
128
136
}
129
- const final = if (H .has_crypto_api ) @as (u64 , @truncate (h .finalInt ())) else h .final ();
137
+ const final = if (H .has_struct_api ) | field_name |
138
+ @field (h , field_name )
139
+ else if (H .has_crypto_api )
140
+ @as (u64 , @truncate (h .finalInt ()))
141
+ else
142
+ h .final ();
130
143
std .mem .doNotOptimizeAway (final );
131
144
132
145
const elapsed_ns = timer .read ();
@@ -340,7 +353,9 @@ fn mode(comptime x: comptime_int) comptime_int {
340
353
}
341
354
342
355
pub fn main () ! void {
343
- const stdout = std .fs .File .stdout ().deprecatedWriter ();
356
+ var stdout_buffer : [0x100 ]u8 = undefined ;
357
+ var stdout_writer = std .fs .File .stdout ().writer (& stdout_buffer );
358
+ const stdout = & stdout_writer .interface ;
344
359
345
360
var buffer : [1024 ]u8 = undefined ;
346
361
var fixed = std .heap .FixedBufferAllocator .init (buffer [0.. ]);
@@ -360,6 +375,7 @@ pub fn main() !void {
360
375
while (i < args .len ) : (i += 1 ) {
361
376
if (std .mem .eql (u8 , args [i ], "--mode" )) {
362
377
try stdout .print ("{}\n " , .{builtin .mode });
378
+ try stdout .flush ();
363
379
return ;
364
380
} else if (std .mem .eql (u8 , args [i ], "--seed" )) {
365
381
i += 1 ;
@@ -397,6 +413,7 @@ pub fn main() !void {
397
413
key_size = try std .fmt .parseUnsigned (usize , args [i ], 10 );
398
414
if (key_size .? > block_size ) {
399
415
try stdout .print ("key_size cannot exceed block size of {}\n " , .{block_size });
416
+ try stdout .flush ();
400
417
std .process .exit (1 );
401
418
}
402
419
} else if (std .mem .eql (u8 , args [i ], "--iterative-only" )) {
@@ -416,6 +433,7 @@ pub fn main() !void {
416
433
417
434
if (test_iterative_only and test_small_key_only ) {
418
435
try stdout .print ("Cannot use iterative-only and small-key-only together!\n " , .{});
436
+ try stdout .flush ();
419
437
usage ();
420
438
std .process .exit (1 );
421
439
}
@@ -428,13 +446,15 @@ pub fn main() !void {
428
446
if (filter == null or std .mem .indexOf (u8 , H .name , filter .? ) != null ) hash : {
429
447
if (! test_iterative_only or H .has_iterative_api ) {
430
448
try stdout .print ("{s}\n " , .{H .name });
449
+ try stdout .flush ();
431
450
432
451
// Always reseed prior to every call so we are hashing the same buffer contents.
433
452
// This allows easier comparison between different implementations.
434
453
if (H .has_iterative_api and ! test_small_key_only ) {
435
454
prng .seed (seed );
436
455
const result = try benchmarkHash (H , count , allocator );
437
456
try stdout .print (" iterative: {:5} MiB/s [{x:0<16}]\n " , .{ result .throughput / (1 * MiB ), result .hash });
457
+ try stdout .flush ();
438
458
}
439
459
440
460
if (! test_iterative_only ) {
@@ -447,6 +467,7 @@ pub fn main() !void {
447
467
result_small .throughput / size ,
448
468
result_small .hash ,
449
469
});
470
+ try stdout .flush ();
450
471
451
472
if (! test_arrays ) break :hash ;
452
473
if (H .has_anytype_api ) | sizes | {
@@ -464,6 +485,7 @@ pub fn main() !void {
464
485
result_ptr .throughput / (1 * MiB ),
465
486
result_ptr .hash ,
466
487
});
488
+ try stdout .flush ();
467
489
}
468
490
}
469
491
}
@@ -476,6 +498,7 @@ pub fn main() !void {
476
498
result_small .throughput / default_small_key_size ,
477
499
result_small .hash ,
478
500
});
501
+ try stdout .flush ();
479
502
480
503
if (! test_arrays ) break :hash ;
481
504
if (H .has_anytype_api ) | sizes | {
@@ -488,6 +511,7 @@ pub fn main() !void {
488
511
result .throughput / (1 * MiB ),
489
512
result .hash ,
490
513
});
514
+ try stdout .flush ();
491
515
}
492
516
try stdout .print (" array ptr: \n " , .{});
493
517
inline for (sizes ) | exact_size | {
@@ -498,6 +522,7 @@ pub fn main() !void {
498
522
result .throughput / (1 * MiB ),
499
523
result .hash ,
500
524
});
525
+ try stdout .flush ();
501
526
}
502
527
}
503
528
}
0 commit comments