Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't build soft-wrapped line segments until they become visible on screen #312

merged 2 commits into from Jun 6, 2019


Copy link

@nathansobo nathansobo commented Jun 5, 2019

馃崘'd with @as-cii

Previously, when we encountered a buffer line that needed to soft wrap, we would intentionally construct and cache all screen lines for that buffer line, even if many of these screen lines weren't visible on screen. This made the code slightly simpler, because we never needed to resume construction of soft-wrapped line segments in the middle of a partially-cached line.

Unfortunately, this led to very bad performance when opening files with a single very long line, as reported in atom/atom#14952. We would end up constructing all screen lines for the entire file rather than just constructing the lines that were visible on screen.

In this PR, we remove the logic that forced us to build all segments of a soft-wrapped line. Instead, we introduce logic to allow construction of screen lines to resume in the middle of a soft wrap. There are two major pieces to this:

  • We restore the bufferColumn when processing soft wrap and folds from the spatial index that occur inside of cached lines.
  • We associate each cached a softWrapIndent integer. If the integer is >= 0, it means the line terminated in a soft wrap, and when resuming, we know to set the inLeadingWhitespace flag to false. If the integer is > 0, we also insert leading soft-wrap whitespace on the next line when resuming after a cached line.

After 20k trials of our randomized test, I'm not seeing any incorrect behavior. Performance when loading a large file is also markedly improved. Here's an example of loading a user-submitted 4.5MB file containing a single line of JSON.


We block the main thread for 8.5 seconds while we pre-cache every screen line.

Screen Shot 2019-06-05 at 3 09 55 PM


We build the screen lines in 113ms. Still longer than I would like, but not a disaster.

Screen Shot 2019-06-05 at 2 57 37 PM

Raw speed is still important, and we're still too slow. If you move your cursor straight to the end of the file, the process will still block the main thread as we compute all the soft wrapped lines. I'm not sure how much room for optimization there is in the raw line construction code path. Perhaps we can do more to compute what we need for soft wraps and avoid constructing lines that are above the viewport as well. But this PR is a good start.

Nathan Sobo and others added 2 commits Jun 5, 2019
@nathansobo nathansobo force-pushed the ns-as/faster-long-lines branch from 2530773 to f845011 Jun 5, 2019
@nathansobo nathansobo merged commit 83cba39 into master Jun 6, 2019
2 checks passed
@nathansobo nathansobo deleted the ns-as/faster-long-lines branch Jun 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

1 participant