Originally, "tty" had two definitions: the hardware (now the emulator) and the driver (interfaced through /dev/pty* or /dev/tty*).
The hardware/emulator was/is responsible for:
- Taking a stream of data and presenting it; this included interpreting control sequences like "move cursor left", "blinking cursor", "clear-screen" although these control sequences were often different among manufacturers.
- Sending keycodes for keys typed by the user; most of these were standard ASCII characters, but some terminals sent propriety keycodes for even standard keys.
The 'tty' driver was responsible for:
- Managing the buffering, in raw or canonical mode; for example, buffering a line of characters until Enter is pressed.
- Managing the control flow; e.g. being able to stop/continue with Cntl-s/Cntl-q.
- Translating propriety keycodes to standard ASCII, where applicable.
- Intercepting certain control characters (like Cntl-c and Backspace) and processing them appropriately (send SIGINT on a Cntl-c or signal an EOF on Cntl-d.
- Canonical display of characters, for example, if
echo
is turned off, then do not send feedback (character typed) back to the terminal.
The terminfo and termcap databases managed what terminal control characters should be sent for an operation (like 'clear-screen'). These control sequences were/are not interpreted by the driver, but by the hardware/emulator.
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.
Best Answer
For the same reason your GUI terminal emulator likely supports tabs (e.g. GNOME Terminal), and if not (e.g.
rxvt
), then for the same reason launching a second GUI terminal app instance doesn't just pull the first one to the foreground and exit, forcing you to use the first instance.I routinely use at least 3 terminal windows in my work, and often more:
Text editor for the server side of the system I'm working on
Text editor for the client side of the same system
Command window for running the server
I rarely need a fourth terminal for running the client program, since it usually runs elsewhere (web app, native GUI app, mobile app, etc.), but if I were developing a CLI client for my server app, I'd have a separate terminal open for it, too.
In the past, before
sudo
became popular, I kept aroot
terminal open all the time.I rarely use Unix/Linux boxes interactively at the console without a GUI these days, but I do often run them headless and access them over SSH. My SSH terminal client of choice supports tabs, configured as above.
One of my current hobby projects has me using a real old glass terminal occasionally, which means I no longer have multiple terminal windows, so I'm finally learning a bit about GNU
screen
, a program I never had much use for before, since I had either multiple console terminals or multiple GUI terminals. And what doesscreen
do? Among other things, you can configure it to give you multiple virtual terminals on a single screen, just like Linux does with Ctrl-Alt-Fx.