keithw/mosh — pull request #531 by cgull (2014-06-15 01:20:01+00:00)
Title:   Performance improvements for Terminal::Framebuffer and Terminal::Display

This replaces pull request #527. This pull request has had some extraneous stuff weeded out, some pushed to other branches, bugs fixed, and (most important) a bunch of time spent in 'git merge -i' to its benefit. But the discussion on that pull request is still background for this one. I've fixed all the bugs I know of, the pull request is comprehensible now, and I think it's ready for Mosh.

To summarize what this does:

* It improves the containers in Terminal::Framebuffer. Terminal::Renditions and Terminal::Cells go on a diet (important when you have 30k of them), Cells use UTF-8 strings instead of vector because std::string is faster everywhere I've tried it (even with different implementation strategies), and Rows are stored in vectors instead of deques (deques do neatly handle scrolling, but they are costly to index and construct/delete). It also reworks some methods to allow slightly more efficient generation of the diff string.
* It rips apart^W^Wrefactors Terminal::Display::new_frame() and put_cell() to use a put_row() instead, and carefully optimizes the per-character loop inside to be much more efficient, and more logically organizes the state necessary for tracking the generation of the diff string. It also reworks character output to reduce the amount of characters generated significantly. Another motivating piece for this was to make both Framebuffers passed into new_frame() const references, instead of having to copy one. That in itself improved performance, but it lead to...
* The last and largest improvement: making the Rows in Framebuffers shared, copy-on-write objects with the help of std::shared_ptr. I knew something like this was possible, but scratched my head for a while on how to do it cleanly. The change ends up being elegant and not very large, though-- thanks to past efforts to ensure const correctness everywhere else in Mosh. This greatly reduces the amount of copying mosh has to do to maintain multiple terminal states (except for one case-- where you cat a large file to your terminal and it's scrolling as fast as it can). This greatly improves Mosh's performance for actual use cases where not much of the display changes from frame to frame, like sitting idle or working in an editor.

It also has various little algorithmic improvements and fixes for pet peeves, but those are fairly straightforward stuff.

I think the shared/COW Rows change also has potential to help with other long-standing feature requests and issues in Mosh, such as versioned prediction and scrollback buffering. I haven't really explored that though.