Files
zig/lib/std/unicode/throughput_test.zig
T
UraniaZPM 485b996b61 Make benchmarking use std.Io.Clock.awake for timing (#31553)
In #31086, the `std.time.Timer` struct was removed, but this broke the last few programs that used it, those being the benchmarking programs for `std.Random`, `std.hash`, `std.crypto` and `std.unicode`. One more is `zig/perf_test.zig`, but as far as I can tell, that one is broken due to changes in file import rules too, unless I'm launching it wrong.

I also spotted some performance and benchmarking issues with the RNGs, detailed in #31554.

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31553
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: UraniaZPM <uraniazpm@noreply.codeberg.org>
Co-committed-by: UraniaZPM <uraniazpm@noreply.codeberg.org>
2026-03-18 21:00:08 +01:00

85 lines
2.6 KiB
Zig

const std = @import("std");
const Io = std.Io;
const time = std.time;
const unicode = std.unicode;
const N = 1_000_000;
const KiB = 1024;
const MiB = 1024 * KiB;
const GiB = 1024 * MiB;
const ResultCount = struct {
count: usize,
throughput: u64,
};
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 = benchTime(io);
var i: usize = 0;
var r: usize = undefined;
while (i < N) : (i += 1) {
r = try @call(
.never_inline,
std.unicode.utf8CountCodepoints,
.{buf},
);
}
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));
return ResultCount{ .count = r, .throughput = throughput };
}
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(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
try stdout.print("short ASCII strings\n", .{});
try stdout.flush();
{
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("ŌŌŌ", 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, 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, 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, io);
try stdout.print(" count: {:5} MiB/s [{d}]\n", .{ result.throughput / (1 * MiB), result.count });
}
try stdout.flush();
}