add benchmark

This commit is contained in:
Yuzucchii 2025-06-04 23:12:33 -05:00
parent 656bc667e6
commit 6fea55d21d
Signed by: yuzucchii
SSH Key Fingerprint: SHA256:3hT0Nn/790kQI9VFVQ2Kfh3Ma3JZe2pST86n1T5G7ww
7 changed files with 277277 additions and 8 deletions

View File

@ -34,3 +34,11 @@
## Sic respondeo:
The Zig Discord server is plagued with modern scum, of course, modern scum will dismiss all of my claims or label them as "dumb" or "you're using it wrong!", has any of these individuals not considered that Zig is over complicated? There is a reason why Andrew Kelley himself detached from the communities [and has spoken in multiple instances](https://andrewkelley.me/post/goodbye-twitter-reddit.html) about the "shitification" of software communities, it's like turning a good community of like-minded programmers into a soydev shill. One good thing that he did was shutting down the r/zig subreddit.
On different note, I defend simplicity and minimalism, so I am not saying that *every* Zig developer who thinks differently is scum, I just say that if you cannot think beyond your viewpoint you will reach nowhere. Lastly, if your software is not straightforward and simple to use, then why criticising someone for now knowing how to use it? The only reasonable way to make software complicated is as long as user friendliness is not a tradeoff for performance or minimalism.
### benchmark for the nerds
benchmark runs total time time/run (avg ± σ) (min ... max) p75 p99 p995
-----------------------------------------------------------------------------------------------------------------------------
aether 2 1m14.271s 37.135s ± 960.345ms (36.456s ... 37.814s) 37.814s 37.814s 37.814s
aether [MEMORY] 54.095MiB ± 0B (54.095MiB ... 54.095MiB) 54.095MiB 54.095MiB 54.095MiB
std.json 2 1m12.731s 36.365s ± 621.288ms (35.926s ... 36.805s) 36.805s 36.805s 36.805s
std.json [MEMORY] 43.420MiB ± 0B (43.420MiB ... 43.420MiB) 43.420MiB 43.420MiB 43.420MiB

277140
benchmarks/10mb.json Normal file

File diff suppressed because it is too large Load Diff

89
benchmarks/main.zig Normal file
View File

@ -0,0 +1,89 @@
// benchmark std.json vs aether
const bigdata = @embedFile("10mb.json");
const std = @import("std");
fn aetherbenchAux(allocator: std.mem.Allocator) !void {
const aether = @import("aether");
const Tokenizer = aether.Tokenizer;
const Language = aether.Language;
var tokenizer: Tokenizer = try .init(allocator, bigdata);
errdefer tokenizer.deinit(allocator);
var self = try allocator.create(Language);
self.* = Language.init;
defer allocator.destroy(self);
defer self.deinit(allocator);
const idx: usize = try self.parse(allocator, &tokenizer);
var root = try self.getValue(allocator, idx);
defer root.deinit(allocator);
try std.testing.expect(root == .object);
//std.debug.print("{}\n", .{root});
}
fn stdjsonbenchAux(allocator: std.mem.Allocator) !void {
const json = std.json;
const root = try json.parseFromSliceLeaky(json.Value, allocator, bigdata, .{
.allocate = .alloc_always,
.duplicate_field_behavior = .@"error",
.max_value_len = 4096,
.ignore_unknown_fields = true,
});
try std.testing.expect(root == .object);
//std.debug.print("{}\n", .{root});
}
pub fn aetherbench(allocator: std.mem.Allocator) void {
aetherbenchAux(allocator) catch @panic("aetherbench failed");
}
pub fn stdjsonbench(allocator: std.mem.Allocator) void {
stdjsonbenchAux(allocator) catch @panic("aetherbench failed");
}
pub fn main() !void {
const zbench = @import("zbench");
const stdout = std.io.getStdOut().writer();
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{};
const allocator = gpa.allocator();
var bench = zbench.Benchmark.init(allocator, .{
.iterations = 2,
});
defer {
bench.deinit();
const deinit_status = gpa.deinit();
if (deinit_status == .leak)
std.debug.panic("Memory leak detected", .{});
}
try bench.add("aether", &aetherbench, .{
.track_allocations = true,
});
try bench.add("std.json", &stdjsonbench, .{
.track_allocations = true,
});
try stdout.writeByte('\n');
try bench.run(stdout);
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(gpa.allocator(), stdout);
},
};
try stdout.writeAll("]\n");
}

View File

@ -1,8 +1,35 @@
pub fn build(b: *@import("std").Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const aether = b.addModule("discord.zig", .{
.root_source_file = b.path("root.zig"),
.link_libc = true,
});
_ = b.addStaticLibrary(.{
.name = "aether",
.root_source_file = b.path("root.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
.target = target,
.optimize = optimize,
});
const benchmarks = b.addExecutable(.{
.name = "benchmarks",
.root_source_file = b.path("benchmarks/main.zig"),
.target = target,
.optimize = optimize,
});
const zbench_module = b.dependency("zbench", .{}).module("zbench");
benchmarks.root_module.addImport("aether", aether);
benchmarks.root_module.addImport("zbench", zbench_module);
b.installArtifact(benchmarks);
const benchmarks_cmd = b.addRunArtifact(benchmarks);
benchmarks_cmd.step.dependOn(b.getInstallStep());
const benchmarks_step = b.step("benchmarks", "Run the benchmarks");
benchmarks_step.dependOn(&benchmarks_cmd.step);
}

View File

@ -6,7 +6,12 @@
.fingerprint = 0x27a0a7c056e7482c,
.minimum_zig_version = "0.15.0-dev.552+bc2f7c754",
.dependencies = .{},
.dependencies = .{
.zbench = .{
.url = "git+https://github.com/hendriknielaender/zBench#c64bb43a3e32c5c62c02058ad7247e072301708d",
.hash = "zbench-0.10.0-YTdc714iAQDO4lTHMnIljYHPZ5v_sNTsw75vAmO1pyT-",
},
},
.paths = .{
"build.zig",
"build.zig.zon",

View File

@ -53,9 +53,9 @@ frame: usize,
/// Initialize a new tokenizer
pub fn init(allocator: mem.Allocator, text: []const u8) mem.Allocator.Error!Self {
const stack = try allocator.alloc(usize, 0x100);
errdefer allocator.free(stack);
const stack = try allocator.alloc(usize, 4096);
@memset(stack, 0);
return .{
.text = text,
.max_position = 0,
@ -84,9 +84,9 @@ fn advance(self: *Self, delta: usize) void {
fn pushFrame(self: *Self, allocator: mem.Allocator) Error!usize {
self.frame += 1;
if (self.frame == self.stack.len) {
const new_stack = try allocator.alloc(usize, self.stack.len * 2);
@memset(new_stack, 0);
@memcpy(new_stack, self.stack);
const new_size = self.stack.len + (self.stack.len >> 1); // 1.5x growth
const new_stack = try allocator.alloc(usize, new_size);
@memcpy(new_stack[0..self.frame], self.stack[0..self.frame]);
allocator.free(self.stack);
self.stack = new_stack;
}

BIN
zig-out/bin/benchmarks Executable file

Binary file not shown.