add benchmark
This commit is contained in:
parent
656bc667e6
commit
6fea55d21d
@ -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
277140
benchmarks/10mb.json
Normal file
File diff suppressed because it is too large
Load Diff
89
benchmarks/main.zig
Normal file
89
benchmarks/main.zig
Normal 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");
|
||||
}
|
31
build.zig
31
build.zig
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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
BIN
zig-out/bin/benchmarks
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user