[GH-ISSUE #266] TextView consumes too much CPU during reindexing/drawing #207

Closed
opened 2026-03-04 01:02:59 +03:00 by kerem · 4 comments
Owner

Originally created by @urandom on GitHub (Apr 12, 2019).
Original GitHub issue: https://github.com/rivo/tview/issues/266

I've noticed that a simple textview, without colors, regions or wrapping will still consume close to a 100% of a cpu core when its being written to, if it contains a lot of text. A scenario like that is pretty easily achievable if one tries to tail a busy log file via a textview. The bulk of that time is taken by the stringWidth function, either through the decomposeString, later on when calculating the line width for the index itself, and finally during iterateString.

An extremely naive fix was to add a simple map as a cache to the stringWidth util function. This removed the entire bottleneck on subsequent scrolls

Originally created by @urandom on GitHub (Apr 12, 2019). Original GitHub issue: https://github.com/rivo/tview/issues/266 I've noticed that a simple textview, without colors, regions or wrapping will still consume close to a 100% of a cpu core when its being written to, if it contains a lot of text. A scenario like that is pretty easily achievable if one tries to tail a busy log file via a textview. The bulk of that time is taken by the stringWidth function, either through the decomposeString, later on when calculating the line width for the index itself, and finally during iterateString. An extremely naive fix was to add a simple map as a cache to the stringWidth util function. This removed the entire bottleneck on subsequent scrolls
kerem closed this issue 2026-03-04 01:02:59 +03:00
Author
Owner

@urandom commented on GitHub (Apr 14, 2019):

I was able to significantly improve the responsiveness of the textview by appending data to the index rather than rebuilding it every time something is written to the buffer. Further optimizations can be had by adding a new parameter to decomposeString to skip calculating the length, since often times it is discarded.

Other things that can be done for even more gains are not rebuilding the index when highlights, colors and regions are changed, but only using or ignoring that information during draw time. This might require a bit more investigation though.

<!-- gh-comment-id:482987888 --> @urandom commented on GitHub (Apr 14, 2019): I was able to significantly improve the responsiveness of the textview by appending data to the index rather than rebuilding it every time something is written to the buffer. Further optimizations can be had by adding a new parameter to decomposeString to skip calculating the length, since often times it is discarded. Other things that can be done for even more gains are not rebuilding the index when highlights, colors and regions are changed, but only using or ignoring that information during draw time. This might require a bit more investigation though.
Author
Owner

@rivo commented on GitHub (Jun 30, 2019):

Sorry, I'm just getting to this now. I'd like to understand better where exactly we have the bottlenecks and why they are there (you mentioned stringWidth() - maybe that function needs to be optimized instead). Could you provide a short demo test program that we can use to kind of benchmark this issue?

<!-- gh-comment-id:507059159 --> @rivo commented on GitHub (Jun 30, 2019): Sorry, I'm just getting to this now. I'd like to understand better where exactly we have the bottlenecks and why they are there (you mentioned `stringWidth()` - maybe that function needs to be optimized instead). Could you provide a short demo test program that we can use to kind of benchmark this issue?
Author
Owner

@urandom commented on GitHub (Jul 1, 2019):

Yes, the stringWidth function is the bottleneck, and appears to be a big one. Since I wasn't sure it can even be optimized, I decided to optimize everything else around it, which did improve things quite a bit. Most of it is exploiting the fact that the textview can only be appended to, so only then does the index need to be rebuilt.

As for a test program, you can use mine: https://github.com/urandom/kd - if you have a kubernetes cluster lying around. Or you can just stick a decently sized log (a couple of hundred lines should do it) and start appending/scroling in the textview demo code to achieve the same result.

<!-- gh-comment-id:507162742 --> @urandom commented on GitHub (Jul 1, 2019): Yes, the stringWidth function is the bottleneck, and appears to be a big one. Since I wasn't sure it can even be optimized, I decided to optimize everything else around it, which did improve things quite a bit. Most of it is exploiting the fact that the textview can only be appended to, so only then does the index need to be rebuilt. As for a test program, you can use mine: https://github.com/urandom/kd - if you have a kubernetes cluster lying around. Or you can just stick a decently sized log (a couple of hundred lines should do it) and start appending/scroling in the textview demo code to achieve the same result.
Author
Owner

@rivo commented on GitHub (Aug 26, 2023):

The TextView component has been completely rewritten. It should be much faster now. If you still find that there are problems with it, please open a new issues.

<!-- gh-comment-id:1694354712 --> @rivo commented on GitHub (Aug 26, 2023): The `TextView` component has been completely rewritten. It should be much faster now. If you still find that there are problems with it, please open a new issues.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#207
No description provided.