mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-09-04 08:48:21 +00:00
It now benchmarks the I/O thread as well for results much closer to what you get when running in real kitty
85 lines
2.5 KiB
Python
Executable file
85 lines
2.5 KiB
Python
Executable file
#!./kitty/launcher/kitty +launch
|
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
|
|
|
import fcntl
|
|
import os
|
|
import select
|
|
import signal
|
|
import struct
|
|
import sys
|
|
import termios
|
|
import time
|
|
from pty import CHILD, fork
|
|
|
|
from kitty.constants import kitten_exe
|
|
from kitty.fast_data_types import ChildMonitor, Screen, safe_pipe
|
|
from kitty.utils import read_screen_size
|
|
|
|
BENCHMARK_WINDOW_ID = 1
|
|
|
|
|
|
def run_parsing_benchmark(cell_width: int = 10, cell_height: int = 20, scrollback: int = 20000) -> None:
|
|
isatty = sys.stdout.isatty()
|
|
if isatty:
|
|
sz = read_screen_size()
|
|
columns, rows = sz.cols, sz.rows
|
|
else:
|
|
columns, rows = 80, 25
|
|
child_pid, master_fd = fork()
|
|
is_child = child_pid == CHILD
|
|
argv = [kitten_exe(), '__benchmark__', '--with-scrollback']
|
|
if is_child:
|
|
while read_screen_size().width != columns * cell_width:
|
|
time.sleep(0.01)
|
|
signal.pthread_sigmask(signal.SIG_SETMASK, ())
|
|
os.execvp(argv[0], argv)
|
|
x_pixels = columns * cell_width
|
|
y_pixels = rows * cell_height
|
|
s = struct.pack('HHHH', rows, columns, x_pixels, y_pixels)
|
|
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, s)
|
|
|
|
child_died = False
|
|
|
|
def on_child_death(window_id: int, died: bool, exit_status: int) -> None:
|
|
nonlocal child_died
|
|
child_died = True
|
|
|
|
child_monitor = ChildMonitor(on_child_death, None)
|
|
|
|
# r_pipe: benchmark polls this; w_pipe: io_thread writes here on data ready
|
|
r_pipe, w_pipe = safe_pipe(False)
|
|
child_monitor.set_wakeup_fd(w_pipe)
|
|
|
|
screen = Screen(None, rows, columns, scrollback, cell_width, cell_height, BENCHMARK_WINDOW_ID)
|
|
child_monitor.add_child(BENCHMARK_WINDOW_ID, child_pid, master_fd, screen)
|
|
child_monitor.start()
|
|
|
|
try:
|
|
while not child_died:
|
|
rd, _, _ = select.select([r_pipe], [], [], 1.0)
|
|
if rd:
|
|
# drain all accumulated wakeup bytes
|
|
try:
|
|
os.read(r_pipe, 256)
|
|
except OSError:
|
|
pass
|
|
child_monitor.parse_input_once()
|
|
finally:
|
|
child_monitor.shutdown_monitor() # io_loop closes master_fd via cleanup_child
|
|
os.close(r_pipe)
|
|
os.close(w_pipe)
|
|
|
|
if isatty:
|
|
lines: list[str] = []
|
|
screen.linebuf.as_ansi(lines.append)
|
|
sys.stdout.write(''.join(lines))
|
|
else:
|
|
sys.stdout.write(str(screen.linebuf))
|
|
|
|
|
|
def main() -> None:
|
|
run_parsing_benchmark()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|