-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move Statistics into module & various minor changes (#70)
- Move Statistics into its own module and parameterise it by type, so it can hold u64s for nanoseconds and usizes for bytes. - Compute statistics on demand rather than pre-computing them in Result. - Add Reading and Readings types, so it can carry more than just nanoseconds without changing most code. - Add JSON examples
- Loading branch information
Showing
14 changed files
with
377 additions
and
329 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,5 +29,7 @@ test "bench test hooks" { | |
.after_all = afterAllHook, | ||
}, | ||
}); | ||
|
||
try stdout.writeAll("\n"); | ||
try bench.run(stdout); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
const std = @import("std"); | ||
const zbench = @import("zbench"); | ||
const test_allocator = std.testing.allocator; | ||
|
||
fn myBenchmark(alloc: std.mem.Allocator) void { | ||
var result: usize = 0; | ||
for (0..2_000) |i| { | ||
std.mem.doNotOptimizeAway(i); | ||
result += i * i; | ||
const buf = alloc.alloc(u8, 1024) catch unreachable; | ||
defer alloc.free(buf); | ||
} | ||
} | ||
|
||
test "bench test json" { | ||
const stdout = std.io.getStdOut().writer(); | ||
var bench = zbench.Benchmark.init(test_allocator, .{}); | ||
defer bench.deinit(); | ||
|
||
try bench.add("My Benchmark 1", myBenchmark, .{ .iterations = 10 }); | ||
|
||
try stdout.writeAll("["); | ||
var iter = try bench.iterator(); | ||
var i: usize = 0; | ||
while (try iter.next()) |step| switch (step) { | ||
.progress => |_| {}, | ||
.result => |x| { | ||
defer x.deinit(); | ||
defer i += 1; | ||
if (0 < i) try stdout.writeAll(", "); | ||
try x.writeJSON(stdout); | ||
}, | ||
}; | ||
try stdout.writeAll("]\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,7 @@ | ||
const std = @import("std"); | ||
const zbench = @import("zbench"); | ||
|
||
fn myBenchmark(_: std.mem.Allocator) void { | ||
var result: usize = 0; | ||
for (0..1_000_000) |i| { | ||
std.mem.doNotOptimizeAway(i); | ||
result += i * i; | ||
} | ||
} | ||
|
||
test "bench test system info" { | ||
test "system info" { | ||
const stdout = std.io.getStdOut().writer(); | ||
var bench = zbench.Benchmark.init(std.testing.allocator, .{}); | ||
defer bench.deinit(); | ||
|
||
const sysinfo = try bench.getSystemInfo(); | ||
try std.fmt.format(stdout, "\n{}\n", .{sysinfo}); | ||
|
||
try bench.add("My Benchmark", myBenchmark, .{}); | ||
try bench.run(stdout); | ||
try stdout.print("\n\n{}\n", .{try zbench.getSystemInfo()}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,33 @@ | ||
const std = @import("std"); | ||
const log = std.log.scoped(.zbench_format); | ||
|
||
pub fn memorySize(bytes: u64, allocator: std.mem.Allocator) ![]const u8 { | ||
const units = .{ "B", "KB", "MB", "GB", "TB" }; | ||
var size: f64 = @floatFromInt(bytes); | ||
var unit_index: usize = 0; | ||
|
||
while (size >= 1024 and unit_index < units.len - 1) : (unit_index += 1) { | ||
size /= 1024; | ||
} | ||
|
||
const unit = switch (unit_index) { | ||
0 => "B", | ||
1 => "KB", | ||
2 => "MB", | ||
3 => "GB", | ||
4 => "TB", | ||
5 => "PB", | ||
6 => "EB", | ||
else => unreachable, | ||
fn FormatJSONArrayData(comptime T: type) type { | ||
return struct { | ||
values: []const T, | ||
|
||
const Self = @This(); | ||
|
||
fn format( | ||
data: Self, | ||
comptime fmt: []const u8, | ||
options: std.fmt.FormatOptions, | ||
writer: anytype, | ||
) !void { | ||
_ = fmt; | ||
_ = options; | ||
try writer.writeAll("["); | ||
for (data.values, 0..) |x, i| { | ||
if (0 < i) try writer.writeAll(", "); | ||
try writer.print("{}", .{x}); | ||
} | ||
try writer.writeAll("]"); | ||
} | ||
}; | ||
|
||
// Format the result with two decimal places if needed | ||
var buf: [64]u8 = undefined; // Buffer for formatting | ||
const formattedSize = try std.fmt.bufPrint(&buf, "{d:.2} {s}", .{ size, unit }); | ||
return allocator.dupe(u8, formattedSize); | ||
} | ||
|
||
/// Pretty-prints the header for the result pretty-print table | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintHeader(writer: anytype) !void { | ||
try writer.print( | ||
"{s:<22} {s:<8} {s:<14} {s:<22} {s:<28} {s:<10} {s:<10} {s:<10}\n", | ||
.{ | ||
"benchmark", | ||
"runs", | ||
"total time", | ||
"time/run (avg ± σ)", | ||
"(min ... max)", | ||
"p75", | ||
"p99", | ||
"p995", | ||
}, | ||
); | ||
const dashes = "-------------------------"; | ||
try writer.print(dashes ++ dashes ++ dashes ++ dashes ++ dashes ++ "\n", .{}); | ||
} | ||
|
||
/// Pretty-prints the name of the benchmark | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintName(name: []const u8, writer: anytype) !void { | ||
try writer.print("{s:<22} ", .{name}); | ||
} | ||
|
||
/// Pretty-prints the number of total operations (or runs) of the benchmark performed | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintTotalOperations(total_operations: u64, writer: anytype) !void { | ||
try writer.print("{d:<8} ", .{total_operations}); | ||
} | ||
|
||
/// Pretty-prints the total time it took to perform all the runs | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintTotalTime(total_time: u64, writer: anytype) !void { | ||
try writer.print("{s:<14} ", .{std.fmt.fmtDuration(total_time)}); | ||
} | ||
|
||
/// Pretty-prints the average (arithmetic mean) and the standard deviation of the durations | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintAvgStd(avg: u64, stddev: u64, writer: anytype) !void { | ||
var buffer: [128]u8 = undefined; | ||
const str = try std.fmt.bufPrint(&buffer, "{} ± {}", .{ | ||
std.fmt.fmtDuration(avg), | ||
std.fmt.fmtDuration(stddev), | ||
}); | ||
try writer.print("{s:<22} ", .{str}); | ||
} | ||
|
||
/// Pretty-prints the minumim and maximum duration | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintMinMax(min: u64, max: u64, writer: anytype) !void { | ||
var buffer: [128]u8 = undefined; | ||
const str = try std.fmt.bufPrint(&buffer, "({} ... {})", .{ | ||
std.fmt.fmtDuration(min), | ||
std.fmt.fmtDuration(max), | ||
}); | ||
try writer.print("{s:<28} ", .{str}); | ||
} | ||
|
||
/// Pretty-prints the 75th, 99th and 99.5th percentile of the durations | ||
/// writer: Type that has the associated method print (for example std.io.getStdOut.writer()) | ||
pub fn prettyPrintPercentiles(p75: u64, p99: u64, p995: u64, writer: anytype) !void { | ||
try writer.print("{s:<10} {s:<10} {s:<10}", .{ | ||
std.fmt.fmtDuration(p75), | ||
std.fmt.fmtDuration(p99), | ||
std.fmt.fmtDuration(p995), | ||
}); | ||
pub fn fmtJSONArray( | ||
comptime T: type, | ||
values: []const T, | ||
) std.fmt.Formatter(FormatJSONArrayData(T).format) { | ||
const data = FormatJSONArrayData(T){ .values = values }; | ||
return .{ .data = data }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.