summaryrefslogtreecommitdiff
path: root/tests_tty_perf.zig
blob: 06ce9cc3e70bef3bdb6d70fdb29f63320720c68e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const std = @import("std");
const h = @import("e2e_harness.zig");

const Harness = h.Harness;
const linux = std.os.linux;

const samples = 5;
const payload_len = 64;

fn nowNs() u64 {
    var ts: linux.timespec = undefined;
    _ = linux.clock_gettime(linux.CLOCK.MONOTONIC, &ts);
    return @intCast(ts.sec * 1_000_000_000 + ts.nsec);
}

fn fillPayload(buf: *[payload_len]u8, sample: usize) []const u8 {
    const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    for (buf, 0..) |*ch, i| ch.* = alphabet[(i + sample * 13) % alphabet.len];

    var marker_buf: [16]u8 = undefined;
    const marker = std.fmt.bufPrint(&marker_buf, "ZTPERF{d}END", .{sample}) catch unreachable;
    const start = payload_len - marker.len;
    @memcpy(buf[start..][0..marker.len], marker);
    return buf[start..payload_len];
}

fn clickBodyRow(hs: *Harness, screen_row: usize) !void {
    var seq_buf: [64]u8 = undefined;
    const seq = try std.fmt.bufPrint(&seq_buf, "\x1b[<0;3;{d}M\x1b[<0;3;{d}m", .{ screen_row, screen_row });
    try hs.send(seq);
}

pub fn main(init: std.process.Init) !void {
    const gpa = init.gpa;
    const args = try init.minimal.args.toSlice(init.arena.allocator());
    if (args.len != 2) {
        std.debug.print("usage: {s} <pardes-exe>\n", .{args[0]});
        return error.BadArgs;
    }

    var hs = try Harness.initArgs(gpa, args[1].ptr, 24, 80, "--tty");
    defer hs.deinit();

    try hs.expectWaitFor("sy /", 6000, "--tty did not start in tty mode");
    try hs.send("clear\r");
    try hs.pump(900);
    try hs.send("\x02");
    try hs.expectWaitFor("nm /", 6000, "Ctrl-b did not leave tty mode");

    var best_us: u64 = std.math.maxInt(u64);
    var total_us: u64 = 0;

    std.debug.print("tty-edit-perf backend=vaxis samples={d} chars_per_sample={d}\n", .{ samples, payload_len });

    var sample: usize = 0;
    while (sample < samples) : (sample += 1) {
        const row = 5 + sample * 3;
        try clickBodyRow(&hs, row);
        try hs.pump(80);
        try hs.send("i");
        try hs.expectWaitFor("in /", 3000, "failed to enter insert mode");

        var payload_buf: [payload_len]u8 = undefined;
        const marker = fillPayload(&payload_buf, sample);

        const t0 = nowNs();
        try hs.send(&payload_buf);
        try hs.expectWaitFor(marker, 10_000, "typed marker never appeared");
        const elapsed_us = (nowNs() - t0) / 1000;

        best_us = @min(best_us, elapsed_us);
        total_us += elapsed_us;
        std.debug.print(" sample {d}: elapsed_us={d} us_per_char={d}\n", .{
            sample + 1,
            elapsed_us,
            elapsed_us / payload_len,
        });

        try hs.send("\x1b");
        try hs.expectWaitFor("nm /", 3000, "failed to leave insert mode");
    }

    std.debug.print("tty-edit-perf summary: best_us={d} avg_us={d} best_us_per_char={d}\n", .{
        best_us,
        total_us / samples,
        best_us / payload_len,
    });
}