feat(benchmark): add benchmark build (with build option) to test frame rate

This commit is contained in:
2024-11-09 01:17:09 +01:00
parent 2d2e63ac63
commit 817d818d4c
3 changed files with 53 additions and 6 deletions

View File

@@ -16,11 +16,11 @@ It contains information about me and my projects as well as blog entries about s
- [ ] How can I support to run a sub-process inside of a given pane / layout?
- [ ] Create demo gifs using [vhs](https://github.com/charmbracelet/vhs)
- [ ] How would I measure my FPS?
- [ ] Could I simulate a corresponding event loop?
- empty user event
- emmit as many as possible through another thread (until the event queue is full?)
- [x] Could I simulate a corresponding event loop?
- emmit as many as possible through another thread (until the event queue is full?) [1023]
- see how fast the application can render each frame and measure the necessary time for each _frame_?
-> determine statistics like, min, max, median, mean, etc.
-> Or buffered writer to the `std.posix.STDOUT_FILENO`?
-> I could use this to see if it makes sense to implement a buffered version using a screen buffer (to only render the differences?)
- seems pretty good (with some exceptions)

View File

@@ -15,6 +15,14 @@ pub fn build(b: *std.Build) void {
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{});
// build options to customize the log message formatting
const benchmark = b.option(bool, "benchmark", "Create a benchmark build (default: false)") orelse false;
const options = b.addOptions();
options.addOption(bool, "benchmark", benchmark);
const options_module = options.createModule();
// Dependencies
const vaxis_dep = b.dependency("vaxis", .{
.optimize = optimize,
@@ -37,6 +45,7 @@ pub fn build(b: *std.Build) void {
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("build_options", options_module);
exe.root_module.addImport("vaxis", vaxis_dep.module("vaxis"));
exe.root_module.addImport("zlog", zlog_dep.module("zlog"));
exe.root_module.addImport("zmd", zmd_dep.module("zmd"));

View File

@@ -1,3 +1,4 @@
const build_options = @import("build_options");
const std = @import("std");
const terminal = @import("terminal.zig");
const zlog = @import("zlog");
@@ -38,6 +39,14 @@ pub fn main() !void {
try app.start();
defer app.stop() catch unreachable;
// Benchmarking
var instants: std.ArrayList(u64) = undefined;
var benchmark_thread: std.Thread = undefined;
if (comptime build_options.benchmark) {
instants = try std.ArrayList(u64).initCapacity(allocator, 512);
benchmark_thread = try std.Thread.spawn(.{}, benchmark, .{&app});
}
// App.Event loop
while (true) {
const event = app.nextEvent();
@@ -68,15 +77,44 @@ pub fn main() !void {
},
else => {},
}
var start_instant: std.time.Instant = undefined;
if (comptime build_options.benchmark) {
start_instant = try std.time.Instant.now();
}
// NOTE: this currently re-renders the screen for every key-press -> which might be a bit of an overkill
const events = try layout.handle(event);
for (events.items) |e| {
app.postEvent(e);
}
try renderer.render(try layout.content());
if (comptime build_options.benchmark) {
const end_instant = try std.time.Instant.now();
try instants.append(end_instant.since(start_instant));
}
}
// TODO: I could use the ascii codes in vaxis
// - see https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b
if (comptime build_options.benchmark) {
benchmark_thread.join();
// print benchmark results
for (instants.items, 1..) |epoch, i| {
_ = i;
const epoch_float: f64 = @floatFromInt(epoch);
std.log.info("{d:.3}", .{epoch_float / std.time.ns_per_ms});
}
instants.deinit();
}
}
fn benchmark(app: *App) void {
std.time.sleep(1 * std.time.ns_per_s);
for (0..511) |_| {
app.postEvent(.{ .key = .{ .cp = 'j' } });
app.postEvent(.{ .key = .{ .cp = 'k' } });
}
app.quit();
}
test {