//! 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_new = @import("../terminal/main.zig"); const Args = struct { mode: Mode = .alloc, /// The number of pages to create sequentially. count: usize = 10_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, /// Use a memory pool to allocate pages from a backing buffer. pool, }; 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), .pool => try benchPool(alloc, args.count), } } noinline fn benchAlloc(count: usize) !void { for (0..count) |_| { _ = try terminal_new.Page.init(terminal_new.page.std_capacity); } } noinline fn benchPool(alloc: Allocator, count: usize) !void { var list = try terminal_new.PageList.init( alloc, terminal_new.page.std_capacity.cols, terminal_new.page.std_capacity.rows, 0, ); defer list.deinit(); for (0..count) |_| { _ = try list.grow(); } }