Can a terminal emulator be as fast as TTY 1-6

terminaltty

I've been trying various terminal emulators lately, from the built-in gnome-terminal, aterm, xterm, wterm, to rxvt. The test I've been doing is in this order:

  1. Open up a tmux window with 2 panes
  2. The left pane will be an verbose-intensive task such as grep a /et/c -r or a simple time seq -f 'blah blah %g' 100000
  3. The right pane will be a vim window with syntax on, opening any file that has more than >100 lines of code.

When the left pane is printing a lot of output, the right pane seems to be very slow and unresponsive, I tried to scroll in vim but it takes 1-2 second for it to change. When I try to press CtrlC on the left pane it waits for more than 10 second before it stopped

When I do the same thing in TTY (pressing CTRL+ALT+(F[1-6])), it doesn't happen and both panes are very responsive.

I've turned of some config such as antialias fonts, turn of coloring, use default settings, and change to xmonad and openbox, but it doesn't change anything.

The result of time seq -f 'blah blah %g' 100000 is not really different among these terminals, but the responsiveness is really different especially when I'm running spitted pane tmux (or other multiplexers). FYI, I'm running all of them in a maximized mode.

I've read about frame buffered terminals but not sure how does it work and how can it be used to speed up my terminal emulator.

So my question is, what makes terminal emulator far slower than TTY? Is there any possibility to make it as fast as TTY? Maybe hardware acceleration or something?. One thing I know, my resolution in X server when running a maximized terminal emulator is 1920×1080, and when I'm running TTY it is less than that, but I'm not sure how this would affect the performance.

Best Answer

When a GUI terminal emulator prints out a string, it has to convert the string to font codepoints, send the codepoints to a font renderer, get back a bitmap and blit that bitmap to the display via the X server.

The font renderer has to retrieve the glyphs and run them (did you know that Truetype/Opentype fonts are programs running inside a virtual machine in the font renderer?). During the process of running each glyph, an insane number of decisions are made with respect to font metrics, kerning (though monospace fonts and kerning don't mix well), Unicode compliance, and that's before we even reach the rasteriser which probably uses sub-pixel addressing. The terminal then has to take the buffer produced by the font rasteriser and blit it to the right place, taking care of pixel format conversions, alpha channels (for sub-pixel addressing), scrolling (which involves more blitting), et cetera.

In comparison, writing a string to a Virtual Terminal running in text mode (note: not a graphical console) involves writing that string to video memory. ‘Hello, World!’ involves writing 13 bytes (13 16-bit words if you want colours, too). The X font rasteriser hasn't even started its stretching exercises and knuckle cracking yet, and we're done. This is why text mode was so incredibly important in decades past. It's very fast to implement. Even scrolling is easier than you think: even on the venerable Motorola 6845-based MDA and CGA, you could scroll the screen vertically by writing a single 8-bit value to a register (could be 16... it's been too long). The screen refresh circuitry did the rest. You were essentially changing the start address of the frame buffer.

There's nothing you can do to make a graphical terminal as fast as a text mode terminal on the same computer. But take heart: there have been computers with slower text modes than the slowest graphical terminal you're ever likely to see on a modern computer. The original IBM PC was pretty bad (DOS did software scrolling, sigh). When I saw my first Minix console on an 80286, I was amazed at the speed of the (jump) scrolling. Progress is good.

Update: how to accelerate the terminal

@poige has already mentioned three in his answer, but here's my own take on them:

  • Decrease the size of the terminal. My own terminals tend to grow till they fill screens, and they get slow as they do that. I get exasperated, annoyed at graphical terminals, then I resize them and everything's better. :)
  • (@poige) Use a different terminal emulator. You can get a huge speed boost at the cost of some modern features. xterm and rxvt work really well, it has a fantastic terminal emulator. I suspect your tests may have showed they perform better than the ‘modern’ ones.
  • (@poige) Don't use scalable fonts. 1986 may call and ask for its terminals back, but you can't deny they're faster. ;)
  • (@poige) Dumb down the font rasteriser by turning off anti-aliasing/sub-pixel addressing and hinting. Most of them allow overrides in environment variables, so you don't have to do this globally. Note: pointless if you choose a bitmap font.
  • This will hurt the most: don't use (multiple panes in) tmux — run two separate terminals side by side. When tmux displays two panes, it has to use terminal directives to move the cursor around a lot. Even though modern terminal libraries are very fast and good at optimising, they're still stealing bytes from your raw terminal bandwidth. To move the cursor to an arbitrary row on a DEC VT-compatible terminal, you send ESC [ row ; col H. That's 6–10 bytes. With multiple terminals, you're segregating the work, doing away with the need for positioning, optimisation, buffering and all the other stuff curses does, and making better use of multiple CPU cores.
Related Question