I've written a small program to compare ncurses performance between various terminal emulators and virtual console. I've found that gnome-terminal performs well in some situations, and poorly in others. When filling a fullscreen window with whitespace, it performs reasonably well. When filling the same area with full stops, it performs pretty bad. I've tried the same program using xterm and getty and both perform very well regardless of what character is being drawn.
My question is, what is going on with gnome-terminal? I'm also curious if can it be improved, or if I'm just doing something wrong here. And finally, is ncurses going to be the best performer for this kind of test in most cases? I ran a similar test changing colors with tput and drawing characters with printf, but its performance was much worse than ncurses.
Here is the source of the test program. It will run until interrupted, filling the screen with randomly colored squares containing either a blank space or a full stop.
#include <ncurses.h>
#include <stdlib.h>
int main() {
// Init ncurses.
initscr();
start_color();
// Create color pairs for all combinations of standard colors.
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
init_pair((i << 4) | j, i, j);
}
}
// Loop forever.
while (1) {
// Get current window dimensions.
int rows, cols;
getmaxyx(stdscr, rows, cols);
// Reset cursor.
move(0, 0);
// Loop rows.
for (int i = 0; i < rows; i++) {
// Loop columns.
for (int j = 0; j < cols; j++) {
// Set a random color pair.
attr_set(0, rand() % 0xff, NULL);
// Draw a character.
printw("."); // SLOW
//printw(" "); // FAST
}
}
// Draw.
refresh();
}
// Cleanup.
endwin();
return 0;
}
ncurses will be "smart about" moving the cursor to points on the screen which should be updated (this is what "cursor optimization" refers to, but the sample program simply walks through each cell on the screen, updating every cell in succession.
The cells differ by the colors — ncurses will notice if successive cells use the same color and refrain from sending color-changing escape sequences in that case (and some special cases of escape sequences are shorter), but otherwise the sample program provides no reason for ncurses to send fewer characters.
The performance issues are due to how fast gnome-terminal can handle changing colors on each cell of the screen — it's going to have a lot more bits per cell than just the 8 bits for "." and 8 bits for color.