-
-
Notifications
You must be signed in to change notification settings - Fork 51
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
Bad CucumberExpression creation performance #200
Comments
I would welcome a pull request for this, but the cache(s) should not be static. Consider extracting the code from the Note that the Please also update the documentation for the |
Ah. Please disregard my previous comment. The |
I don't see the issue with I don't think the static cache will cause a real memory usage issue because on my project with ~150 stepdefs and ~400 test scenarios, the Caching the Good point on thread-safety. |
I was hoping to keep a non-static cache in the And while this proposal does make steps towards cucumber/cucumber-jvm#2035 it would become mostly obsolete the moment we drop Would it be possible to create an optimization for |
I'll try to optimize |
I've refactored the
The
The code is pretty simple and elegant. The
The code is a bit more complex and slower than The full
So the Should I do a PR with only this optimization with |
👓 What did you see?
On my project with about 150 stepdefs and about 400 test scenarios, the IntelliJ profiler says the
CucumberExpression.<init>
method takes 25.9% of the total CPU time. This is because the method is called for all step defs and for all test scenarios. I think the performance could be better.✅ What did you expect to see?
I expect
CucumberExpression.<init>
to avoid unnecessary processing (contributes to #2035).I understand that
cucumber-java8
can introduce dynamic behavior which requires parsing the expressions for each test scenario. However, I think we can safely cache everything that is constant and does not depend oncucumber-java8
. I identitifed the following performance improvement points inCucumberExpression
:TreeRegex
creation: inCucumberExpression
constructor, this object serves to get some "metadata" about a regular expression itself (i.e. not depending on context). Thus, two identical regular expressions will lead to the sameTreeRegp
, so the creation is cacheable.The original code:
could be replaced by (
treeRegexps
is a staticMap<String, TreeRegexp>
):calls to
escapeRegex
in therewriteToRegex
method are done on theNode.text()
content: two identicalNode.text()
will lead to the same escaped result, independently of the context. Thus, the result ofescapeRegex
is cacheable.The original code:
can be replaced by (
escapedTexts
is a staticMap<String, String>
):These two optimization points lead to four combinations to be benchmarked (original version is
createExpression0
). The benchmark consists in creating 400 times five different expressions:Caching the
TreeRegex
creation lead to 22% performance improvement and using both methods lead to 44% performance improvement.On a real project with about 150 stepdefs and 400 test scenarios, the IntelliJ Profiler runs is about 7700 ms and says that
CucumberExpression.<init>
is:I suggest to use the variant createExpression3 and I would be happy to propose a PR.
📦 Which tool/library version are you using?
Cucumber 7.10.1
🔬 How could we reproduce it?
The benchmark with the four variants is in
cucumberexpressions.zip
Steps to reproduce the behavior:
Create a Maven project with the following dependencies:
Run the benchmark
The text was updated successfully, but these errors were encountered: