-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
An attempt to improve performance of terminal/parser #17336
Comments
This is some of the most impressive stuff I've seen in a while lol. You're using a vim script to turn the typescript compiler into test VT output. The entire branch has so cool ideas and helpful bits! It'll take me a while to go through it and test it out. 🙂
Very clear actually! Using lookup tables for the parser is something I wanted to do for a very long time. I'm extremely happy that you did it. I feel like that tables are still superior even if they aren't faster, because it's easier to verify their correctness and debug them. It may take a little while for me to get a chance to look at your code in more detail, as I'm currently working on some difficult changes to ConPTY which will also improve performance a lot (it'll make Windows Terminal >10x faster!). That aside, these performance numbers look wrong:
You should get at least 100MB/s with our current parser (without lookup tables). If those numbers are from OpenConsole, please ensure you have built it in Release mode and that you don't have node.js running in the background. node.js subscribes to console events which slows down all console applications by 10x. (Even those that don't have anything to do with node.js!) |
I was experimenting with something like this today and kind of realized that LUTs for dispatch during parsing isn't quite right: We should instead defer parsing to specialized subroutines to consume as much input as they can. For instance, the CSI parser should be its own subroutine and parse all parameters at once before returning. This gives the largest performance boost for me. Afterwards, we could dispatch the resulting type of sequence (e.g. based on the terminator) using a LUT of function pointers. |
A bit embarrassing that I'm not sure what you mean. If something like this: for (auto end = _currentString.data() + _currentString.size(); p != end; p++)
{
if (*p >= L'0' && *p <= '9')
{
_AccumulateTo(*p, currentParameter);
}
else
{
break;
}
} I think you are right. The less back to state machine, the more performance gain. At least it's true on my x64 system. Without this, it may even run slower than on ARM64 (AMD 3600 vs 8cx Gen 3). At first I wanted to parse the whole param and subparam list like a regular string parser, but that need writing much my own code, so... I gave up. Also, good to know you're interested in this. You give too much praise for me. In fact, I dig into the code for another reason and after accidentally seeing this, I can't stop myself from trying to do it. It's literally "quick and dirty" and I'm sure you can do much better. I should post these after your first comment, just too lazy to that, as I need a translation tool to translate my thoughts. |
Yeah, pretty much exactly like that. I wrote a small tokenizer for It doesn't support many of our |
Description of the new feature/enhancement
Currently
StateMachine
use many if-else branches which may not an efficient way to implement a state machine. It could be improved by using a table approach.Proposed technical implementation details (optional)
A quick and dirty implement lays on https://github.com/flyingcat/terminal/tree/vtparser
codegen.ps1
to generate a function pointer table to execute state transition.stateMachine.hpp|cpp
. It has a demo build on vtparser_apply branch.OutputStateMachineEngine
and use CRTP to reduce virtual calls, as the separation seems only for test and actually no need for runtime dispatch.ActionExecute
andActionCsiDispatch
, directly dispatch them on corresponding char.Some surprise:
_ActionParam
.TraceOnEvent
andTraceCharInput
will reduce a lot of time.Benchmarks (*_P for plain text, *_V for nvim vt output):
Sorry for the bad English and messy code. Hope the idea is clear enough.
The text was updated successfully, but these errors were encountered: