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
merged 2 commits into from Jun 6, 2019

Conversation

Projects
None yet
1 participant
@nathansobo
Copy link
Contributor

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.

Before

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

After

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.

nathansobo and others added some commits Jun 5, 2019

Don't build soft-wrapped line segments beyond the requested endScreenRow
Co-Authored-By: Antonio Scandurra <as-cii@github.com>

@nathansobo nathansobo force-pushed the ns-as/faster-long-lines branch from 2530773 to f845011 Jun 5, 2019

@nathansobo nathansobo referenced this pull request Jun 5, 2019

Merged

Upgrade text buffer #19453

@nathansobo nathansobo merged commit 83cba39 into master Jun 6, 2019

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

@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
You can鈥檛 perform that action at this time.