-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Improving Qute Escaper to be as branch-free as possible #45546
Conversation
Using the benchmark at mkouba/qute-benchmarks#1 shows these differences in perf - now:
vs before
which is a good improvement - which tends to pay-off more as the number of chars increases Fyi @mkouba the relevant ones are using 10000 samples since with just 100 the data are very predictable for my CPU model and you cannot really see the benefits of reducing the number of branches |
This comment has been minimized.
This comment has been minimized.
@galderz on mkouba/qute-benchmarks#1 this implementation should really shine with native image, since it doesn't use |
This comment has been minimized.
This comment has been minimized.
independent-projects/qute/core/src/main/java/io/quarkus/qute/JsonEscaper.java
Outdated
Show resolved
Hide resolved
independent-projects/qute/core/src/main/java/io/quarkus/qute/JsonEscaper.java
Show resolved
Hide resolved
I had to rewrite the
Aren't those numbers swapped given the fact that
Ok 👍 |
independent-projects/qute/core/src/main/java/io/quarkus/qute/JsonEscaper.java
Show resolved
Hide resolved
Numbers still look the same? Did you checked 🙏?
Ops 🤣 I copied in the wrong order , let me fix it |
The HTML one can still made faster, working on it |
dd0393c
to
d4d3d81
Compare
d4d3d81
to
a085c01
Compare
Status for workflow
|
🎊 PR Preview 04deb60 has been successfully built and deployed to https://quarkus-pr-main-45546-preview.surge.sh/version/main/guides/
|
independent-projects/qute/core/src/main/java/io/quarkus/qute/HtmlEscaper.java
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
a085c01
to
1939891
Compare
This comment has been minimized.
This comment has been minimized.
I will provide soon some up-to-date numbers of the html version too |
These are the numbers while using the
Which, as anticipated, are not "wow" - with a small regression in case the pattern of escaping is fully predictable (see
Still not a huge win - since I didn't modified the original algorithm at
This "double lookup" form a data-dependency chain, since we have to load the index before accessing the replacement which is the most relevant factor compared to the original code which just need to correctly speculate the result of the branch instruction (the A better approach would use a long[256] (similar to Json), but would requires going "all in" and not use Let me know if you have further questions. |
I've further pushed 1cd3ae3 which is using some knowledge of how branch prediction work (which can use some history of the previous taken branch address not just the current one) to improve it another bit, although without modifying the base class. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@franz1981 Could you pls squash the commits before we merge?
1cd3ae3
to
b57c128
Compare
Done @mkouba ! |
This is a show case of the approach at lemire/Code-used-on-Daniel-Lemire-s-blog#116 but biased for the one and two replacement latin chars case.
It could be expanded to cover for non-latin and the 6 bytes replacement too, with more painfull and complex (in term of logic) changes - but it looks already complex as it is IMO.
Feedbacks are wellcome as questions.
I didn't yet benchmarked it (is sadly low in my prio list - so IDK when I'll have time to contribute a proper bench which stress the branch-predictor in qute-benchmark) - and there's a good chance my "bet" to use
StringBuilder
to simplify it, making use of the horriblesetLength
in the hot path, won't pay off.In such unfortunate case, I will move to using char[] despite it requires latinness checks due to compact string, on String construction :"(