Register and share your invite link to earn from video plays and referrals.

Mitchell Hashimoto
@mitchellh
Co-founder of @Superlogical. Creator of Ghostty. 👻 Prev founded @HashiCorp, created Vagrant, Terraform, Vault, and others.
Joined January 2008
150 Following    221K Followers
Btw this is why computer science matters. Yes, you can self teach it if you really want to (I personally wouldn't have had the discipline, so college was a way better force). However you learn it, the theoretical fundamentals matter and get applied to work every single day.
Show more
If you're interested in "how" or "why": the major culprit is that each row in Alacritty has 32 bytes of metadata and each cell is 24 bytes. In Ghostty, every row and cell is represented by exactly 8 byte each. How do we do this? The first major culprit is styles. Alacritty stores the full cell style alongside each cell (foreground, background, underline, etc.). Ghostty stores a 16-bit style ID and de-dupes all styles into a look-aside custom reference-counted hash table. MOST cells are unstyled, and when there are styles MOST styles are shared, and when styles are shared MOST are repeated in a run (multiple cells with the same style in a row). Put this all together, and the tradeoff on compute to access it doesn't even end up being slower. Next, codepoints. Alacritty stores multi-codepoint graphemes (like, Emoji) by having an 8-byte nullable pointer to a `Vec`. This hurts doubly: (1) its almost always null (because multi-codepoint is rare) yet you pay an 8 byte cost on every cell and (2) every multi-codepoint grapheme triggers a heap allocation to make that Vec. Ghostty stores single codepoints inline, but multiple codepoints in a look-aside table. The memory for this table uses a custom bitmap-tracked chunk-allocator (since grapheme frequency follows a measurable curve we calculated by scanning various online texts). The presence of graphemes is marked by a 2-bit content tag in our packed 64-bit cell. To keep the key small in the hash table, its limited to a 16-bit unsigned int that is an offset from a base pointer. Okay, the astute systems programmer will quickly notice there are a lot of 16-bit integers and ask: so this is all limited to a max of ~65K values? Nay. We maintain our grid using a linked list of contiguous ~400KB memory chunks (which themselves are in a memory pool using a custom allocator to speed up alloc/free). Each memory chunk is limited to 2^16. If/when we reach a limit, we move to the next page. In practice, this really doesn't happen except under pathological cases... the important point is we handle it. Lots, lots, lots more details, but thats a 10,000 foot view. These things alone account for ~95% of the difference of our uncompressed vs. Alacritty's uncompressed memory usage. (Theres also a reason why Alacritty's data structures aren't trivially compressable but thats a whole other topic)
Show more