History

video/out/kitty: make kitty vo ten times faster by avoiding strlen

When playing a video, 55% of CPU used in strlen, callgraph flip_page: ta_talloc_strdup_append , ta_talloc_asprintf_append and ta_talloc_strndup_append . Before the fix: 2 fps when playing 1080p 24 fps video (--vo-kitty-use-shm=no), 24 fps after the fix. video/out/kitty: move bstr cmd to priv

Sami Farin committed 1 year ago

Commit fa9c2a31 parent 38ad1ed1 file · +38 −26Browse files

Unified · Split

video/out/vo_kitty.c+38−26
@@ -48,7 +48,7 @@ · 47 unmodified lines
4848 #define DEFAULT_WIDTH 80
4949 #define DEFAULT_HEIGHT 25
5050
51−static inline void write_str(const char *s)
51+static inline void write_bstr(bstr bs)
5252 {
5353 // On POSIX platforms, write() is the fastest method. It also is the only
5454 // one that allows atomic writes so mpv’s output will not be interrupted
@@ -57,25 +57,31 @@ static inline void write_str(const char *s) · 2 unmodified lines
5757 // exceeding PIPE_BUF, but at least Linux does seem to implement it that
5858 // way.
5959 #if HAVE_POSIX
60− int remain = strlen(s);
60+ size_t remain = bs.len;
61+ unsigned char *pos = bs.start;
6162 while (remain > 0) {
62− ssize_t written = write(STDOUT_FILENO, s, remain);
63+ ssize_t written = write(STDOUT_FILENO, pos, remain);
6364 if (written < 0)
6465 return;
6566 remain -= written;
66− s += written;
67+ pos += written;
6768 }
6869 #else
69− printf("%s", s);
70+ fwrite(bs.start, 1, bs.len, stdout);
7071 fflush(stdout);
7172 #endif
7273 }
7374
75+static inline void write_str(unsigned char* s)
76+{
77+ write_bstr(bstr0(s));
78+}
79+
7480 #define KITTY_ESC_IMG "\033_Ga=T,f=24,s=%d,v=%d,C=1,q=2,m=1;"
7581 #define KITTY_ESC_IMG_SHM "\033_Ga=T,t=s,f=24,s=%d,v=%d,C=1,q=2,m=1;%s\033\\"
7682 #define KITTY_ESC_CONTINUE "\033_Gm=%d;"
77−#define KITTY_ESC_END "\033\\"
78−#define KITTY_ESC_DELETE_ALL "\033_Ga=d;\033\\"
83+static const bstr KITTY_ESC_END = bstr0_lit("\033\\");
84+static const bstr KITTY_ESC_DELETE_ALL = bstr0_lit("\033_Ga=d;\033\\");
7985
8086 struct vo_kitty_opts {
8187 int width, height, top, left, rows, cols;
@@ -91,6 +97,7 @@ struct priv { · 9 unmodified lines
9197 char *shm_path, *shm_path_b64;
9298 int buffer_size, output_size;
9399 int shm_fd;
100+ bstr cmd;
94101
95102 int left, top, width, height, cols, rows;
96103
@@ -126,6 +133,7 @@ static void free_bufs(struct vo* vo) · 29 unmodified lines
126133
127134 talloc_free(p->frame);
128135 talloc_free(p->output);
136+ talloc_free(p->cmd.start);
129137
130138 if (p->opts.use_shm) {
131139 close_shm(p);
@@ -177,7 +185,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) · 45 unmodified lines
177185 struct priv *p = vo->priv;
178186
179187 vo->want_redraw = true;
180− write_str(KITTY_ESC_DELETE_ALL);
188+ write_bstr(KITTY_ESC_DELETE_ALL);
181189 if (p->opts.config_clear)
182190 write_str(TERM_ESC_CLEAR_SCREEN);
183191
@@ -292,36 +300,40 @@ done: · 108 unmodified lines
292300
293301 static void flip_page(struct vo *vo)
294302 {
295− struct priv* p = vo->priv;
296−
297− if (p->buffer == NULL)
303+ struct priv *p = vo->priv;
304+ if (!p->buffer)
298305 return;
299306
300− char *cmd = talloc_asprintf(NULL, TERM_ESC_GOTO_YX, p->top, p->left);
307+ p->cmd.len = 0;
308+
309+ // Start with ESC to position the cursor
310+ bstr_xappend_asprintf(NULL, &p->cmd, TERM_ESC_GOTO_YX, p->top, p->left);
301311
302312 if (p->opts.use_shm) {
303− cmd = talloc_asprintf_append(cmd, KITTY_ESC_IMG_SHM, p->width, p->height, p->shm_path_b64);
313+ bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_IMG_SHM,
314+ p->width, p->height, p->shm_path_b64);
304315 } else {
305− if (p->output == NULL) {
306− talloc_free(cmd);
316+ if (!p->output) {
307317 return;
308318 }
309319
310− cmd = talloc_asprintf_append(cmd, KITTY_ESC_IMG, p->width, p->height);
311− for (int offset = 0, noffset;; offset += noffset) {
312− if (offset)
313− cmd = talloc_asprintf_append(cmd, KITTY_ESC_CONTINUE, offset < p->output_size);
314− noffset = MPMIN(4096, p->output_size - offset);
315− cmd = talloc_strndup_append(cmd, p->output + offset, noffset);
316− cmd = talloc_strdup_append(cmd, KITTY_ESC_END);
320+ bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_IMG, p->width, p->height);
321+
322+ for (int offset = 0; offset < p->output_size; ) {
323+ int chunk = MPMIN(4096, p->output_size - offset);
324+
325+ if (offset > 0)
326+ bstr_xappend_asprintf(NULL, &p->cmd, KITTY_ESC_CONTINUE,
327+ offset + chunk < p->output_size);
317328
318− if (offset >= p->output_size)
319− break;
329+ // Append at max chunk bytes
330+ bstr_xappend(NULL, &p->cmd, (bstr){p->output + offset, chunk});
331+ bstr_xappend(NULL, &p->cmd, KITTY_ESC_END);
332+ offset += chunk;
320333 }
321334 }
322335
323− write_str(cmd);
324− talloc_free(cmd);
336+ write_bstr(p->cmd);
325337
326338 #if HAVE_POSIX
327339 if (p->opts.use_shm)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t