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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output buffer #374

Closed
wants to merge 4 commits into from
Closed

Output buffer #374

wants to merge 4 commits into from

Conversation

keeslinp
Copy link

Initial attempt at adding an output buffer so that we don't have to push out all of the changes every render. It's still a draft because there are a few bugs I still need to work out (running btm or other programs that use vertical pipes for some reason don't render correctly until after a resize) but I wanted to leave it up here while I work those out to get preliminary feedback.

@keeslinp
Copy link
Author

Preliminary performance tests have been very promising. Even in debug mode this branch is much more responsive than main.

The way I have been testing is that I open two panes and run btm in one of them (anything that frequently updates should do) and then see how laggy the other pane is. On main it is so laggy that you can see the cursor appear and disappear every tick. This branch makes it so you can't even tell it is rendering (input is still smooth).

That being said, this is definitely not a silver bullet, opening something complex like vim and jumping around between files/opening internal UI is still very slow (although still a bit faster than main)

NOTE: I have been testing this on a huge monitor to try and strain things a bit.

@imsnif
Copy link
Member

imsnif commented Apr 26, 2021

This is very cool :)

Initial comments:
As you say, this solution is not a silver bullet. It can definitely be a temporary improvement though.
A better more permanent solution would probably be something like: have the Grid update an "intermediate" buffer every time the viewport content changes. (eg. when printing a character)
Then we don't need to create buffers on render or diff them. I think this might actually be simpler, but I'm not 100% sure about it. What do you think?

@keeslinp
Copy link
Author

A better more permanent solution would probably be something like: have the Grid update an "intermediate" buffer every time the viewport content changes. (eg. when printing a character)
Then we don't need to create buffers on render or diff them. I think this might actually be simpler, but I'm not 100% sure about it. What do you think?

I'm not sure I follow. I would still need to diff them correct? I do like the idea of avoiding iterating over the whole screen each tick, this just seemed easier for a first pass, but maybe I am missing something.

@keeslinp
Copy link
Author

Or are you thinking of a different route altogether where it is maintaining a list of "pending changes" and the render just becomes flushing those changes out? I think that would be more performant, but probably also more potential for bugs when it gets out of sync?

@imsnif
Copy link
Member

imsnif commented Apr 28, 2021

Or are you thinking of a different route altogether where it is maintaining a list of "pending changes" and the render just becomes flushing those changes out? I think that would be more performant, but probably also more potential for bugs when it gets out of sync?

Yes, exactly! I think the only things that should get it out of sync are pane/window resizes and tab switches (unless I'm missing something) and thankfully there's another PR open that addresses those cases: #318
So we could probably hook into that functionality once it's merged and make it do a full force-render in those cases. If we find some case that we're missing we can have it do a full force-render too.

We might have to iterate over it a little bit ofc... what do you think? Or would you prefer to merge this solution as a "temporary" solution until we do that? I'm not sure what will be less work.

@keeslinp
Copy link
Author

Or are you thinking of a different route altogether where it is maintaining a list of "pending changes" and the render just becomes flushing those changes out? I think that would be more performant, but probably also more potential for bugs when it gets out of sync?

Yes, exactly! I think the only things that should get it out of sync are pane/window resizes and tab switches (unless I'm missing something) and thankfully there's another PR open that addresses those cases: #318
So we could probably hook into that functionality once it's merged and make it do a full force-render in those cases. If we find some case that we're missing we can have it do a full force-render too.

We might have to iterate over it a little bit ofc... what do you think? Or would you prefer to merge this solution as a "temporary" solution until we do that? I'm not sure what will be less work.

I'm game to give it a shot! I'll see if I can pull something together tonight.

@keeslinp
Copy link
Author

I took at stab at the solution we talked about and I think it is going to be a lot harder than we were expecting. There's a lot of stuff like linewrapping and moving rows that we'd have to duplicate that is not trivial. Pretty much all of the logic in grid.rs would be affected. If you see a better way I'd love some input cause maybe I am missing something that will make this a lot simpler.

@imsnif
Copy link
Member

imsnif commented Apr 29, 2021

I took at stab at the solution we talked about and I think it is going to be a lot harder than we were expecting. There's a lot of stuff like linewrapping and moving rows that we'd have to duplicate that is not trivial. Pretty much all of the logic in grid.rs would be affected. If you see a better way I'd love some input cause maybe I am missing something that will make this a lot simpler.

Yeah, I see what you mean... as soon as we start scrolling (even just adding a new line) inside a pane, things become a little complex. Right - so let's go with your original solution for now. I think even that alone should give us a pretty nice performance boost. What say you?

@keeslinp
Copy link
Author

I took at stab at the solution we talked about and I think it is going to be a lot harder than we were expecting. There's a lot of stuff like linewrapping and moving rows that we'd have to duplicate that is not trivial. Pretty much all of the logic in grid.rs would be affected. If you see a better way I'd love some input cause maybe I am missing something that will make this a lot simpler.

Yeah, I see what you mean... as soon as we start scrolling (even just adding a new line) inside a pane, things become a little complex. Right - so let's go with your original solution for now. I think even that alone should give us a pretty nice performance boost. What say you?

Yeah I think I agree. This solution definitely needs some more fine-tuning first (there's currently some weird issues with first renders I need to sort out) and I want to take another look at it from a performance perspective to make sure there isn't any low-hanging fruit

@imsnif
Copy link
Member

imsnif commented Feb 20, 2023

Already implemented

@imsnif imsnif closed this Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants