crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.28k stars 281 forks source link

perf: speed up SetColors by ~15-25% #879

Closed joshka closed 6 months ago

joshka commented 7 months ago

The SetColors command was executing SetForegroundColor and then SetBackgroundColor, which writes 2 extra characters per cell compared to writing both colors in one command. This resulted in about 15-25% more FPS (19->24 fps) on a fullscreen (171x51) app that writes every cell with a different foreground and background color, compared to separately using the SetForegroundColor and SetBackgroundColor commands (iTerm2, M2 Macbook Pro).

The app is the colors_rgb example in Ratatui, which writes every cell with a different foreground and background color in a loop. The CrosstermBackend was changed to use SetColors instead of SetForegroundColor and SetBackgroundColor.


Note: this only effects non-windows performance.

Perf gains will vary depending on the terminal emulator. Testing on alacritty and kitty didn't see the same bump, but they were much faster to start with (~42-45 FPS). I suspect there's probably a badly performing code path for mutliple SGR commands in iTerm2.

There are other performance gains to come in the SetAttributes, SetStyle, etc. methods Additionally, the Color commands use indexed 8-bit colors (Esc[5;<fg>m) instead of the shorter 3/4 bit colors, whice likely implies even shorter: E.g. Red on White (bright versions) is currently: Esc[38;5;8mEsc[48;5;15m (19 chars) but should be: Esc[91;97m (8 chars).

joshka commented 7 months ago

Before:

image

After:

image
TimonPost commented 6 months ago

We can fix CI later.