Repository navigation
Conversation
|
Comparison with master using onig: Some wins but mostly regression for cold highlight (fancy usually wins on warm highlight though). @keith-hall I've tried letting Fable have another look at fancy-regex (relevant commits here: https://github.com/Keats/fancy-regex/commits/cold-perf/ they are all pretty short except 0de5d3e and ee914fe) and the results using that branch (minus ee914fe since it just got added) compared to the previous run above that uses current fancy-regex main branch: With those changes, fancy-regex beats oniguruma. |
|
Ah and even with those patches, using I'll add a flag to toggle for full |
Yay, dream come true! Thanks, I will take a look at the changes and see what I can apply to fancy-regex.
That is a shame... I wonder whether any strategies like JIT compilation (which I have seen other regex crates offering) would help and whether it is feasible... |
|
I'm wondering whether the prefilter should be in fancy-regex tbh. I've added an option to use full regex set or prefilter in the last commit and you can play with it but you get a 15-60% perf improvement at the cost of 2-10x more memory usage in the full regex set usage. I don't think this tradeoff makes a lot of sense in practice, the improvement is rarely worth the memory usage for pretty much any fancy-regex user. With a local Zola benchmark, I had a 100k pages site rendering in 10s with regexset and 15s with prefilter but the regexset used 12GB of memory while the prefilter used 6GB (and the difference would only grow if I highlight more languages). |
|
Makes sense, feel free to prototype how it could look in fancy-regex and we'll see the impact and whether we want to include it. (Would it look identical to 7ed0d70, or perhaps make use of some internal methods, and/or perhaps be based on the seek pattern etc?) |
|
I'm not sure exactly where the limit would be. Should the prefilter from 7ed0d70 be moved (and probably optimized a bit, I used bool because it was simpler but we can do bit twiddling with u64 and it should be faster/smaller?) and then exposed and users can build their own For the prefilter: I would need to check what's available in the internal methods of fancy-regex, maybe we can simplify stuff. If we wanted to move more to fancy-regex, we would need to add I can work on a PR, just let me know where the limit should be. |
|
Probably makes sense to do bit twiddling, to have the shared implementation as performant as possible... |
|
We can put it behind a feature flag in case others don't need it |
|
In one commit: Keats/fancy-regex@dfdb09c |
|
As it will be behind a feature likely only Giallo will use, I'd be tempted to say include what you need, whatever makes sense to have in fancy-regex... |
|
If it's only giallo then I will just keep it in giallo and if someone else needs it, the branch is always there to add it in fancy-regex |
8a2c312 to
2bd5f00
Compare
|
FYI @keith-hall the ClassSeq changes from https://github.com/Keats/fancy-regex/commits/cold-perf/ give the cold benchmarks of giallo a good range of 0 to 30% speedup. It also does improve a bit some warm benchmarks, some -6/8% for JS/TS. |
|
I haven't forgotten, its on my todo list - I feel those changes are complicated and I will need some time to fully understand them before I merge them in. Thanks for the reminder and your patience 🙂 (I saw that the rust coreutils implementation wanted to switch to fancy-regex, so I ended up spending some time to add leftmost-longest semantics as an option, which took some of my time 😉) |
|
To make it simple, I've put all the unapplied fancy-regex patches (including the ClassSeq ones) into https://github.com/Keats/fancy-regex/tree/class-seq |
Use changes from fancy-regex lazy branch Prebuild bytesets and update benches Do not build a regexset for a single regex
Only a win in warm cases but up to -13% for shell for example
|
I wanted to help you by sending individual PRs but I don't want to send slop and I don't know the fancy-regex crate enough to write it myself so I'm not sure I'm actually helping. I'll list individual branches with AI generated commits with benches/tests for the things that move the needle a lot rather than one branch so it's easier to review: |
|
Thanks, I applied the lookbehind one at fancy-regex/fancy-regex#285 |
|
And I opened a PR for the ClassSeq changes at fancy-regex/fancy-regex#290, will force me to review it ;) |
|
@keith-hall benchmarks comparing master with onig and this branch with fancy-regex/class-seq2: https://gist.github.com/Keats/85dfd018d732fdf77d86a3a4d2ff9606 This branch has a lot of optimizations that could certainly be used with onig as well so not an perfect comparison but good enough. The 2 biggest regressions are PHP (rust-lang/regex#1396 for the upstream fix) and shell (slevithan/oniguruma-parser#28 the shellscript has a pretty bad pattern for fancy-regex that is not optimized). I'll hardcode replacements for those in giallo until it gets fixed upstream but it's almost a clear win everywhere. The jquery file highlight is even 2x faster than syntect on my machine, that's almost entirely the required bytes filter at work. Look at those warm numbers 👀 |
|
Nice one, thanks for sharing. I wonder whether the required byte filter would help improve performance for findutils: uutils/findutils#864 Do you think it is worth trying to apply a similar suffix extraction optimization in fancy-regex? How is the memory usage now btw? |
Worth a try. It depends a lot on the patterns, eg it was a huge win for JS but almost a no-op on a few other lang. Do they use a single regex? Multiple? I haven't looked at their code. They also should check if they want to disable prefilters etc
Maybe? Shiki runs https://github.com/slevithan/oniguruma-parser/tree/main/src/optimizer on all the textmate grammars so giallo would not benefit from it and I don't know who else is using crazy regexes like textmate/sublime.
Not too bad. Something like 50% higher than onig still. I've removed the public RegexSet strategy though as with all the optimizations it was same speed or slower than the walk while using twice the memory. I still use them internally in a few places though. |
No description provided.