diff --git a/lib/std/Random/benchmark.zig b/lib/std/Random/benchmark.zig index e704471e9a..8ddaac8a36 100644 --- a/lib/std/Random/benchmark.zig +++ b/lib/std/Random/benchmark.zig @@ -5,7 +5,6 @@ const builtin = @import("builtin"); const std = @import("std"); const Io = std.Io; const time = std.time; -const Timer = time.Timer; const Random = std.Random; const KiB = 1024; @@ -72,7 +71,11 @@ const Result = struct { const long_block_size: usize = 8 * 8192; const short_block_size: usize = 8; -pub fn benchmark(comptime H: anytype, bytes: usize, comptime block_size: usize) !Result { +pub fn benchTime(io: Io) i96 { + return Io.Clock.awake.now(io).nanoseconds; +} + +pub fn benchmark(comptime H: anytype, io: Io, bytes: usize, comptime block_size: usize) !Result { var rng = blk: { if (H.init_u8s) |init| { break :blk H.ty.init(init[0..].*); @@ -86,12 +89,11 @@ pub fn benchmark(comptime H: anytype, bytes: usize, comptime block_size: usize) var block: [block_size]u8 = undefined; var offset: usize = 0; - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); while (offset < bytes) : (offset += block.len) { rng.fill(block[0..]); } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(@as(f64, @floatFromInt(bytes)) / elapsed_s)); @@ -187,7 +189,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print("{s} (long outputs)\n", .{R.name}); try stdout.flush(); - const result_long = try benchmark(R, count, long_block_size); + const result_long = try benchmark(R, io, count, long_block_size); try stdout.print(" {:5} MiB/s\n", .{result_long.throughput / (1 * MiB)}); } } @@ -198,7 +200,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print("{s} (short outputs)\n", .{R.name}); try stdout.flush(); - const result_short = try benchmark(R, count, short_block_size); + const result_short = try benchmark(R, io, count, short_block_size); try stdout.print(" {:5} MiB/s\n", .{result_short.throughput / (1 * MiB)}); } } @@ -211,7 +213,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print("{s} (cryptographic, long outputs)\n", .{R.name}); try stdout.flush(); - const result_long = try benchmark(R, count, long_block_size); + const result_long = try benchmark(R, io, count, long_block_size); try stdout.print(" {:5} MiB/s\n", .{result_long.throughput / (1 * MiB)}); } } @@ -222,7 +224,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print("{s} (cryptographic, short outputs)\n", .{R.name}); try stdout.flush(); - const result_short = try benchmark(R, count, short_block_size); + const result_short = try benchmark(R, io, count, short_block_size); try stdout.print(" {:5} MiB/s\n", .{result_short.throughput / (1 * MiB)}); } } diff --git a/lib/std/crypto/benchmark.zig b/lib/std/crypto/benchmark.zig index d77dbb5f32..3090dac0cd 100644 --- a/lib/std/crypto/benchmark.zig +++ b/lib/std/crypto/benchmark.zig @@ -6,7 +6,6 @@ const std = @import("std"); const Io = std.Io; const mem = std.mem; const time = std.time; -const Timer = std.time.Timer; const crypto = std.crypto; const KiB = 1024; @@ -45,15 +44,18 @@ const parallel_hashes = [_]Crypto{ const block_size: usize = 8 * 8192; -pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 { +pub fn benchTime(io: Io) i96 { + return Io.Clock.awake.now(io).nanoseconds; +} + +pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int, io: Io) !u64 { const blocks_count = bytes / block_size; var block: [block_size]u8 = undefined; random.bytes(&block); var h = Hash.init(.{}); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); for (0..blocks_count) |_| { h.update(&block); } @@ -61,7 +63,7 @@ pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 h.final(&final); std.mem.doNotOptimizeAway(final); - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(bytes / elapsed_s)); @@ -74,13 +76,12 @@ pub fn benchmarkHashParallel(comptime Hash: anytype, comptime bytes: comptime_in defer allocator.free(data); random.bytes(data); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); var final: [Hash.digest_length]u8 = undefined; try Hash.hashParallel(data, &final, .{}, allocator, io); std.mem.doNotOptimizeAway(final); - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(bytes / elapsed_s)); @@ -109,7 +110,7 @@ const macs = [_]Crypto{ Crypto{ .ty = crypto.auth.cmac.CmacAes128, .name = "aes-cmac" }, }; -pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { +pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int, io: Io) !u64 { var in: [512 * KiB]u8 = undefined; random.bytes(in[0..]); @@ -119,13 +120,12 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { var mac: [Mac.mac_length]u8 = undefined; var offset: usize = 0; - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); while (offset < bytes) : (offset += in.len) { Mac.create(mac[0..], in[0..], key[0..]); mem.doNotOptimizeAway(&mac); } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(bytes / elapsed_s)); @@ -135,7 +135,7 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { const exchanges = [_]Crypto{Crypto{ .ty = crypto.dh.X25519, .name = "x25519" }}; -pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_count: comptime_int) !u64 { +pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_count: comptime_int, io: Io) !u64 { std.debug.assert(DhKeyExchange.shared_length >= DhKeyExchange.secret_length); var secret: [DhKeyExchange.shared_length]u8 = undefined; @@ -144,8 +144,7 @@ pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_c var public: [DhKeyExchange.shared_length]u8 = undefined; random.bytes(public[0..]); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < exchange_count) : (i += 1) { @@ -155,7 +154,7 @@ pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_c mem.doNotOptimizeAway(&out); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(exchange_count / elapsed_s)); @@ -177,8 +176,7 @@ pub fn benchmarkSignature(comptime Signature: anytype, comptime signatures_count const msg = [_]u8{0} ** 64; const key_pair = Signature.KeyPair.generate(io); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < signatures_count) : (i += 1) { @@ -186,7 +184,7 @@ pub fn benchmarkSignature(comptime Signature: anytype, comptime signatures_count mem.doNotOptimizeAway(&sig); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(signatures_count / elapsed_s)); @@ -206,8 +204,7 @@ pub fn benchmarkSignatureVerification(comptime Signature: anytype, comptime sign const key_pair = Signature.KeyPair.generate(io); const sig = try key_pair.sign(&msg, null); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < signatures_count) : (i += 1) { @@ -215,7 +212,7 @@ pub fn benchmarkSignatureVerification(comptime Signature: anytype, comptime sign mem.doNotOptimizeAway(&sig); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(signatures_count / elapsed_s)); @@ -235,8 +232,7 @@ pub fn benchmarkBatchSignatureVerification(comptime Signature: anytype, comptime element.* = Signature.BatchElement{ .sig = sig, .msg = &msg, .public_key = key_pair.public_key }; } - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < signatures_count) : (i += 1) { @@ -244,7 +240,7 @@ pub fn benchmarkBatchSignatureVerification(comptime Signature: anytype, comptime mem.doNotOptimizeAway(&sig); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = batch.len * @as(u64, @intFromFloat(signatures_count / elapsed_s)); @@ -261,8 +257,7 @@ const kems = [_]Crypto{ pub fn benchmarkKem(comptime Kem: anytype, comptime kems_count: comptime_int, io: std.Io) !u64 { const key_pair = Kem.KeyPair.generate(io); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < kems_count) : (i += 1) { @@ -270,7 +265,7 @@ pub fn benchmarkKem(comptime Kem: anytype, comptime kems_count: comptime_int, io mem.doNotOptimizeAway(&e); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(kems_count / elapsed_s)); @@ -283,8 +278,7 @@ pub fn benchmarkKemDecaps(comptime Kem: anytype, comptime kems_count: comptime_i const e = key_pair.public_key.encaps(io); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < kems_count) : (i += 1) { @@ -292,7 +286,7 @@ pub fn benchmarkKemDecaps(comptime Kem: anytype, comptime kems_count: comptime_i mem.doNotOptimizeAway(&ss2); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(kems_count / elapsed_s)); @@ -301,8 +295,7 @@ pub fn benchmarkKemDecaps(comptime Kem: anytype, comptime kems_count: comptime_i } pub fn benchmarkKemKeyGen(comptime Kem: anytype, comptime kems_count: comptime_int, io: std.Io) !u64 { - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < kems_count) : (i += 1) { @@ -310,7 +303,7 @@ pub fn benchmarkKemKeyGen(comptime Kem: anytype, comptime kems_count: comptime_i mem.doNotOptimizeAway(&key_pair); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(kems_count / elapsed_s)); @@ -337,7 +330,7 @@ const aeads = [_]Crypto{ Crypto{ .ty = crypto.aead.isap.IsapA128A, .name = "isapa128a" }, }; -pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64 { +pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int, io: Io) !u64 { var in: [512 * KiB]u8 = undefined; random.bytes(in[0..]); @@ -350,14 +343,13 @@ pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64 random.bytes(nonce[0..]); var offset: usize = 0; - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); while (offset < bytes) : (offset += in.len) { Aead.encrypt(in[0..], tag[0..], in[0..], &[_]u8{}, nonce, key); try Aead.decrypt(in[0..], in[0..], tag, &[_]u8{}, nonce, key); } mem.doNotOptimizeAway(&in); - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(2 * bytes / elapsed_s)); @@ -370,15 +362,14 @@ const aes = [_]Crypto{ Crypto{ .ty = crypto.core.aes.Aes256, .name = "aes256-single" }, }; -pub fn benchmarkAes(comptime Aes: anytype, comptime count: comptime_int) !u64 { +pub fn benchmarkAes(comptime Aes: anytype, comptime count: comptime_int, io: Io) !u64 { var key: [Aes.key_bits / 8]u8 = undefined; random.bytes(key[0..]); const ctx = Aes.initEnc(key); var in = [_]u8{0} ** 16; - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < count) : (i += 1) { @@ -386,7 +377,7 @@ pub fn benchmarkAes(comptime Aes: anytype, comptime count: comptime_int) !u64 { } } mem.doNotOptimizeAway(&in); - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(count / elapsed_s)); @@ -399,15 +390,14 @@ const aes8 = [_]Crypto{ Crypto{ .ty = crypto.core.aes.Aes256, .name = "aes256-8" }, }; -pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int) !u64 { +pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int, io: Io) !u64 { var key: [Aes.key_bits / 8]u8 = undefined; random.bytes(key[0..]); const ctx = Aes.initEnc(key); var in = [_]u8{0} ** (8 * 16); - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < count) : (i += 1) { @@ -415,7 +405,7 @@ pub fn benchmarkAes8(comptime Aes: anytype, comptime count: comptime_int) !u64 { } } mem.doNotOptimizeAway(&in); - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(8 * count / elapsed_s)); @@ -468,8 +458,7 @@ fn benchmarkPwhash( const needs_salt = strHashFnInfo.params.len == 4 and strHashFnInfo.params[3].type != std.Io; const salt: [16]u8 = .{0} ** 16; - var timer = try Timer.start(); - const start = timer.lap(); + const start = benchTime(io); { var i: usize = 0; while (i < count) : (i += 1) { @@ -483,7 +472,7 @@ fn benchmarkPwhash( mem.doNotOptimizeAway(&buf); } } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = elapsed_s / count; @@ -554,7 +543,7 @@ pub fn main(init: std.process.Init) !void { inline for (hashes) |H| { if (filter == null or std.mem.find(u8, H.name, filter.?) != null) { - const throughput = try benchmarkHash(H.ty, mode(128 * MiB)); + const throughput = try benchmarkHash(H.ty, mode(128 * MiB), io); try stdout.print("{s:>17}: {:10} MiB/s\n", .{ H.name, throughput / (1 * MiB) }); try stdout.flush(); } @@ -570,7 +559,7 @@ pub fn main(init: std.process.Init) !void { inline for (macs) |M| { if (filter == null or std.mem.find(u8, M.name, filter.?) != null) { - const throughput = try benchmarkMac(M.ty, mode(128 * MiB)); + const throughput = try benchmarkMac(M.ty, mode(128 * MiB), io); try stdout.print("{s:>17}: {:10} MiB/s\n", .{ M.name, throughput / (1 * MiB) }); try stdout.flush(); } @@ -578,7 +567,7 @@ pub fn main(init: std.process.Init) !void { inline for (exchanges) |E| { if (filter == null or std.mem.find(u8, E.name, filter.?) != null) { - const throughput = try benchmarkKeyExchange(E.ty, mode(1000)); + const throughput = try benchmarkKeyExchange(E.ty, mode(1000), io); try stdout.print("{s:>17}: {:10} exchanges/s\n", .{ E.name, throughput }); try stdout.flush(); } @@ -610,7 +599,7 @@ pub fn main(init: std.process.Init) !void { inline for (aeads) |E| { if (filter == null or std.mem.find(u8, E.name, filter.?) != null) { - const throughput = try benchmarkAead(E.ty, mode(128 * MiB)); + const throughput = try benchmarkAead(E.ty, mode(128 * MiB), io); try stdout.print("{s:>17}: {:10} MiB/s\n", .{ E.name, throughput / (1 * MiB) }); try stdout.flush(); } @@ -618,7 +607,7 @@ pub fn main(init: std.process.Init) !void { inline for (aes) |E| { if (filter == null or std.mem.find(u8, E.name, filter.?) != null) { - const throughput = try benchmarkAes(E.ty, mode(100000000)); + const throughput = try benchmarkAes(E.ty, mode(100000000), io); try stdout.print("{s:>17}: {:10} ops/s\n", .{ E.name, throughput }); try stdout.flush(); } @@ -626,7 +615,7 @@ pub fn main(init: std.process.Init) !void { inline for (aes8) |E| { if (filter == null or std.mem.find(u8, E.name, filter.?) != null) { - const throughput = try benchmarkAes8(E.ty, mode(10000000)); + const throughput = try benchmarkAes8(E.ty, mode(10000000), io); try stdout.print("{s:>17}: {:10} ops/s\n", .{ E.name, throughput }); try stdout.flush(); } diff --git a/lib/std/hash/benchmark.zig b/lib/std/hash/benchmark.zig index 4b900a94a1..0f5d908173 100644 --- a/lib/std/hash/benchmark.zig +++ b/lib/std/hash/benchmark.zig @@ -4,7 +4,6 @@ const builtin = @import("builtin"); const std = @import("std"); const Io = std.Io; const time = std.time; -const Timer = time.Timer; const hash = std.hash; const KiB = 1024; @@ -111,7 +110,11 @@ const Result = struct { const block_size: usize = 8 * 8192; -pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Allocator) !Result { +pub fn benchTime(io: Io) i96 { + return Io.Clock.awake.now(io).nanoseconds; +} + +pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Allocator, io: Io) !Result { var blocks = try allocator.alloc(u8, bytes); defer allocator.free(blocks); random.bytes(blocks); @@ -131,7 +134,7 @@ pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Alloc break :blk .init(); }; - var timer = try Timer.start(); + const start = benchTime(io); for (0..block_count) |i| { h.update(blocks[i * block_size ..][0..block_size]); } @@ -143,7 +146,7 @@ pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Alloc h.final(); std.mem.doNotOptimizeAway(final); - const elapsed_ns = timer.read(); + const elapsed_ns = benchTime(io) - start; const elapsed_s = @as(f64, @floatFromInt(elapsed_ns)) / time.ns_per_s; const size_float: f64 = @floatFromInt(block_size * block_count); @@ -155,14 +158,14 @@ pub fn benchmarkHash(comptime H: anytype, bytes: usize, allocator: std.mem.Alloc }; } -pub fn benchmarkHashSmallKeys(comptime H: anytype, key_size: usize, bytes: usize, allocator: std.mem.Allocator) !Result { +pub fn benchmarkHashSmallKeys(comptime H: anytype, key_size: usize, bytes: usize, allocator: std.mem.Allocator, io: Io) !Result { var blocks = try allocator.alloc(u8, bytes); defer allocator.free(blocks); random.bytes(blocks); const key_count = bytes / key_size; - var timer = try Timer.start(); + const start = benchTime(io); var sum: u64 = 0; for (0..key_count) |i| { @@ -182,7 +185,7 @@ pub fn benchmarkHashSmallKeys(comptime H: anytype, key_size: usize, bytes: usize }; sum +%= final; } - const elapsed_ns = timer.read(); + const elapsed_ns = benchTime(io) - start; const elapsed_s = @as(f64, @floatFromInt(elapsed_ns)) / time.ns_per_s; const size_float: f64 = @floatFromInt(key_count * key_size); @@ -204,6 +207,7 @@ pub fn benchmarkHashSmallKeysArrayPtr( comptime key_size: usize, bytes: usize, allocator: std.mem.Allocator, + io: Io, ) !Result { var blocks = try allocator.alloc(u8, bytes); defer allocator.free(blocks); @@ -211,7 +215,7 @@ pub fn benchmarkHashSmallKeysArrayPtr( const key_count = bytes / key_size; - var timer = try Timer.start(); + const start = benchTime(io); var sum: u64 = 0; for (0..key_count) |i| { @@ -231,7 +235,7 @@ pub fn benchmarkHashSmallKeysArrayPtr( }; sum +%= final; } - const elapsed_ns = timer.read(); + const elapsed_ns = benchTime(io) - start; const elapsed_s = @as(f64, @floatFromInt(elapsed_ns)) / time.ns_per_s; const throughput: u64 = @intFromFloat(@as(f64, @floatFromInt(bytes)) / elapsed_s); @@ -252,6 +256,7 @@ pub fn benchmarkHashSmallKeysArray( comptime key_size: usize, bytes: usize, allocator: std.mem.Allocator, + io: Io, ) !Result { var blocks = try allocator.alloc(u8, bytes); defer allocator.free(blocks); @@ -260,7 +265,7 @@ pub fn benchmarkHashSmallKeysArray( const key_count = bytes / key_size; var i: usize = 0; - var timer = try Timer.start(); + const start = benchTime(io); var sum: u64 = 0; while (i < key_count) : (i += 1) { @@ -280,7 +285,7 @@ pub fn benchmarkHashSmallKeysArray( }; sum +%= final; } - const elapsed_ns = timer.read(); + const elapsed_ns = benchTime(io) - start; const elapsed_s = @as(f64, @floatFromInt(elapsed_ns)) / time.ns_per_s; const throughput: u64 = @intFromFloat(@as(f64, @floatFromInt(bytes)) / elapsed_s); @@ -293,14 +298,14 @@ pub fn benchmarkHashSmallKeysArray( }; } -pub fn benchmarkHashSmallApi(comptime H: anytype, key_size: usize, bytes: usize, allocator: std.mem.Allocator) !Result { +pub fn benchmarkHashSmallApi(comptime H: anytype, key_size: usize, bytes: usize, allocator: std.mem.Allocator, io: Io) !Result { var blocks = try allocator.alloc(u8, bytes); defer allocator.free(blocks); random.bytes(blocks); const key_count = bytes / key_size; - var timer = try Timer.start(); + const start = benchTime(io); var sum: u64 = 0; for (0..key_count) |i| { @@ -320,7 +325,7 @@ pub fn benchmarkHashSmallApi(comptime H: anytype, key_size: usize, bytes: usize, }; sum +%= final; } - const elapsed_ns = timer.read(); + const elapsed_ns = benchTime(io) - start; const elapsed_s = @as(f64, @floatFromInt(elapsed_ns)) / time.ns_per_s; const throughput: u64 = @intFromFloat(@as(f64, @floatFromInt(bytes)) / elapsed_s); @@ -454,7 +459,7 @@ pub fn main(init: std.process.Init) !void { // This allows easier comparison between different implementations. if (H.has_iterative_api and !test_small_key_only) { prng.seed(seed); - const result = try benchmarkHash(H, count, allocator); + const result = try benchmarkHash(H, count, allocator, io); try stdout.print(" iterative: {:5} MiB/s [{x:0<16}]\n", .{ result.throughput / (1 * MiB), result.hash }); try stdout.flush(); } @@ -462,7 +467,7 @@ pub fn main(init: std.process.Init) !void { if (!test_iterative_only) { if (key_size) |size| { prng.seed(seed); - const result_small = try benchmarkHashSmallKeys(H, size, count, allocator); + const result_small = try benchmarkHashSmallKeys(H, size, count, allocator, io); try stdout.print(" small keys: {:3}B {:5} MiB/s {} Hashes/s [{x:0<16}]\n", .{ size, result_small.throughput / (1 * MiB), @@ -476,9 +481,9 @@ pub fn main(init: std.process.Init) !void { inline for (sizes) |exact_size| { if (size == exact_size) { prng.seed(seed); - const result_array = try benchmarkHashSmallKeysArray(H, exact_size, count, allocator); + const result_array = try benchmarkHashSmallKeysArray(H, exact_size, count, allocator, io); prng.seed(seed); - const result_ptr = try benchmarkHashSmallKeysArrayPtr(H, exact_size, count, allocator); + const result_ptr = try benchmarkHashSmallKeysArrayPtr(H, exact_size, count, allocator, io); try stdout.print(" array: {:5} MiB/s [{x:0<16}]\n", .{ result_array.throughput / (1 * MiB), result_array.hash, @@ -493,7 +498,7 @@ pub fn main(init: std.process.Init) !void { } } else { prng.seed(seed); - const result_small = try benchmarkHashSmallKeys(H, default_small_key_size, count, allocator); + const result_small = try benchmarkHashSmallKeys(H, default_small_key_size, count, allocator, io); try stdout.print(" small keys: {:3}B {:5} MiB/s {} Hashes/s [{x:0<16}]\n", .{ default_small_key_size, result_small.throughput / (1 * MiB), @@ -507,7 +512,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print(" array:\n", .{}); inline for (sizes) |exact_size| { prng.seed(seed); - const result = try benchmarkHashSmallKeysArray(H, exact_size, count, allocator); + const result = try benchmarkHashSmallKeysArray(H, exact_size, count, allocator, io); try stdout.print(" {d: >3}B {:5} MiB/s [{x:0<16}]\n", .{ exact_size, result.throughput / (1 * MiB), @@ -518,7 +523,7 @@ pub fn main(init: std.process.Init) !void { try stdout.print(" array ptr: \n", .{}); inline for (sizes) |exact_size| { prng.seed(seed); - const result = try benchmarkHashSmallKeysArrayPtr(H, exact_size, count, allocator); + const result = try benchmarkHashSmallKeysArrayPtr(H, exact_size, count, allocator, io); try stdout.print(" {d: >3}B {:5} MiB/s [{x:0<16}]\n", .{ exact_size, result.throughput / (1 * MiB), diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig index c02f550a4a..d759c77ab1 100644 --- a/lib/std/unicode/throughput_test.zig +++ b/lib/std/unicode/throughput_test.zig @@ -2,7 +2,6 @@ const std = @import("std"); const Io = std.Io; const time = std.time; const unicode = std.unicode; -const Timer = std.time.Timer; const N = 1_000_000; @@ -15,12 +14,14 @@ const ResultCount = struct { throughput: u64, }; -fn benchmarkCodepointCount(buf: []const u8) !ResultCount { - var timer = try Timer.start(); +fn benchTime(io: Io) i96 { + return Io.Clock.awake.now(io).nanoseconds; +} +fn benchmarkCodepointCount(buf: []const u8, io: Io) !ResultCount { const bytes = N * buf.len; - const start = timer.lap(); + const start = benchTime(io); var i: usize = 0; var r: usize = undefined; while (i < N) : (i += 1) { @@ -30,7 +31,7 @@ fn benchmarkCodepointCount(buf: []const u8) !ResultCount { .{buf}, ); } - const end = timer.read(); + const end = benchTime(io); const elapsed_s = @as(f64, @floatFromInt(end - start)) / time.ns_per_s; const throughput = @as(u64, @intFromFloat(@as(f64, @floatFromInt(bytes)) / elapsed_s)); @@ -38,44 +39,45 @@ fn benchmarkCodepointCount(buf: []const u8) !ResultCount { return ResultCount{ .count = r, .throughput = throughput }; } -pub fn main() !void { +pub fn main(init: std.process.Init) !void { // Size of buffer is about size of printed message. + const io = init.io; var stdout_buffer: [0x100]u8 = undefined; - var stdout_writer = Io.File.stdout().writer(&stdout_buffer); + var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); const stdout = &stdout_writer.interface; try stdout.print("short ASCII strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("abc"); + const result = try benchmarkCodepointCount("abc", io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("short Unicode strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("ŌŌŌ"); + const result = try benchmarkCodepointCount("ŌŌŌ", io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("pure ASCII strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("hello" ** 16); + const result = try benchmarkCodepointCount("hello" ** 16, io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("pure Unicode strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("こんにちは" ** 16); + const result = try benchmarkCodepointCount("こんにちは" ** 16, io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.print("mixed ASCII/Unicode strings\n", .{}); try stdout.flush(); { - const result = try benchmarkCodepointCount("Hyvää huomenta" ** 16); + const result = try benchmarkCodepointCount("Hyvää huomenta" ** 16, io); try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count }); } try stdout.flush();