bench/page-init

This commit is contained in:
Mitchell Hashimoto
2024-02-22 19:51:38 -08:00
parent 424f121104
commit 7ad94caaeb
7 changed files with 95 additions and 5 deletions

14
src/bench/page-init.sh Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
#
# This is a trivial helper script to help run the page init benchmark.
# You probably want to tweak this script depending on what you're
# trying to measure.
# Uncomment to test with an active terminal state.
# ARGS=" --terminal"
hyperfine \
--warmup 10 \
-n alloc \
"./zig-out/bin/bench-page-init --mode=alloc${ARGS} </tmp/ghostty_bench_data"

60
src/bench/page-init.zig Normal file
View File

@ -0,0 +1,60 @@
//! This benchmark tests the speed to create a terminal "page". This is
//! the internal data structure backing a terminal screen. The creation speed
//! is important because it is one of the primary bottlenecks for processing
//! large amounts of plaintext data.
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const cli = @import("../cli.zig");
const terminal = @import("../terminal/main.zig");
const Args = struct {
mode: Mode = .alloc,
/// The number of pages to create sequentially.
count: usize = 20_000,
/// This is set by the CLI parser for deinit.
_arena: ?ArenaAllocator = null,
pub fn deinit(self: *Args) void {
if (self._arena) |arena| arena.deinit();
self.* = undefined;
}
};
const Mode = enum {
/// The default allocation strategy of the structure.
alloc,
};
pub const std_options: std.Options = .{
.log_level = .debug,
};
pub fn main() !void {
// We want to use the c allocator because it is much faster than GPA.
const alloc = std.heap.c_allocator;
// Parse our args
var args: Args = .{};
defer args.deinit();
{
var iter = try std.process.argsWithAllocator(alloc);
defer iter.deinit();
try cli.args.parse(Args, alloc, &args, &iter);
}
// Handle the modes that do not depend on terminal state first.
switch (args.mode) {
.alloc => try benchAlloc(args.count),
}
}
noinline fn benchAlloc(count: usize) !void {
for (0..count) |_| {
_ = try terminal.new.Page.init(terminal.new.Page.std_capacity);
}
}

View File

@ -143,4 +143,5 @@ pub const ExeEntrypoint = enum {
bench_stream,
bench_codepoint_width,
bench_grapheme_break,
bench_page_init,
};

View File

@ -10,4 +10,5 @@ pub usingnamespace switch (build_config.exe_entrypoint) {
.bench_stream => @import("bench/stream.zig"),
.bench_codepoint_width => @import("bench/codepoint-width.zig"),
.bench_grapheme_break => @import("bench/grapheme-break.zig"),
.bench_page_init => @import("bench/page-init.zig"),
};

View File

@ -48,8 +48,9 @@ pub usingnamespace if (builtin.target.isWasm()) struct {
pub usingnamespace @import("wasm.zig");
} else struct {};
/// The new stuff. TODO: remove this before merge.
pub const new = @import("new/main.zig");
test {
@import("std").testing.refAllDecls(@This());
_ = @import("new/main.zig");
}

View File

@ -1,6 +1,8 @@
const builtin = @import("builtin");
const page = @import("page.zig");
pub const Terminal = @import("Terminal.zig");
pub const Page = page.Page;
test {
@import("std").testing.refAllDecls(@This());

View File

@ -91,6 +91,16 @@ pub const Page = struct {
const grapheme_bytes_default = grapheme_count_default * grapheme_chunk;
const GraphemeMap = AutoOffsetHashMap(Offset(Cell), Offset(u21).Slice);
/// The standard capacity for a page that doesn't have special
/// requirements. This is enough to support a very large number of cells.
/// The standard capacity is chosen as the fast-path for allocation.
pub const std_capacity: Capacity = .{
.cols = 250,
.rows = 250,
.styles = 128,
.grapheme_bytes = 1024,
};
/// The size of this page.
pub const Size = struct {
cols: size.CellCountInt,
@ -319,9 +329,10 @@ pub const Cell = packed struct(u64) {
// const total_size = alignForward(
// usize,
// Page.layout(.{
// .cols = 333,
// .rows = 81,
// .styles = 32,
// .cols = 250,
// .rows = 250,
// .styles = 128,
// .grapheme_bytes = 1024,
// }).total_size,
// std.mem.page_size,
// );