-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add cache for RegExp.test #3802
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
Conversation
lib/Runtime/Library/RegexHelper.cpp
Outdated
|
||
if (useCache && cachedValue == input) | ||
{ | ||
return JavascriptBoolean::ToVar(cache[cacheIndex].result, scriptContext); |
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.
return JavascriptBoolean::ToVar(cache[cacheIndex].result, scriptContext); [](start = 12, length = 73)
In case of a cache hit Is it still worth to do the slow lookup in chk build and validate against cached value?
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.
seems like a good idea
struct RegExpTestCache | ||
{ | ||
bool result; | ||
Field(JavascriptString*) input; |
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.
What do you think about making this a weak reference to the string?
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.
I originally tried this and had problems due to ArenaLiteralStrings. These are only used in a couple of places and really don't seem that useful, so I decided to remove them altogether and replace them with normal recycler managed strings.
352b260
to
d4c10fb
Compare
lib/Runtime/Library/RegexHelper.cpp
Outdated
const bool isGlobal = pattern->IsGlobal(); | ||
const bool isSticky = pattern->IsSticky(); | ||
|
||
if (useCache && cacheHit) |
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.
useCache && [](start = 12, length = 11)
nit: no need of this as cacheHit can only be true if useCache was true.
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.
3834be2
to
94491e8
Compare
Merge pull request #3802 from MikeHolman:regextest It seems to be a common enough pattern where people will create a RegExp and test a small number of unique strings many times. For this, I added a simple cache of size 8 on the RegExp object for RegExp.test, which caches the result for some given input string. I disable the cache it in case of using global or sticky, since the result can change depending on lastIndex and caching likely wouldn't help those patterns. After experimentation I decided on size 8, because there were rapidly diminishing returns at size 16 and at size 4 I saw a big increase in cache misses. I tried dynamic sizing as well, but megamorphic cases would quickly max out the cache and the polymorphic cases didn't seem to get much benefit above size 8, so it seemed better to avoid the overhead of resizing and stick with a fixed sized cache. Improves perf of angular by about 6%.
…atches and used a cached value Regression from chakra-core#3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260
…r RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from #3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260
…xp.$1 after RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from #3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260
…y update RegExp.$1 after RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from #3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260
[1.8>1.9] [MERGE #4607 @boingoing] OS#14763260: Correctly update RegExp.$1 after RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from chakra-core/ChakraCore#3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260 Reviewed-By: chakrabot <chakrabot@users.noreply.github.com>
[1.9>master] [1.8>1.9] [MERGE #4607 @boingoing] OS#14763260: Correctly update RegExp.$1 after RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from chakra-core/ChakraCore#3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260 Reviewed-By: chakrabot <chakrabot@users.noreply.github.com>
[1.8>1.9] [MERGE #4607 @boingoing] OS#14763260: Correctly update RegExp.$1 after RegExp.prototype.test matches and used a cached value Merge pull request #4607 from boingoing:FixRegExpTestCache Regression from chakra-core/ChakraCore#3802 - if we hit the cache, we don't update the Regex constructor object with the last match and so retrieving properties about the match from the regex constructor object fails. Fixed by adding an invalidation mechanism to the `JavascriptRegExpConstructor`. If we hit the cache, we'll mark the Regex constructor object last match properties as invalidated and we will then compute them on-demand the first time they're needed. Fixes: https://microsoft.visualstudio.com/web/wi.aspx?id=14763260 Reviewed-By: chakrabot <chakrabot@users.noreply.github.com>
It seems to be a common enough pattern where people will create a RegExp and test a small number of unique strings many times.
For this, I added a simple cache of size 8 on the RegExp object for RegExp.test, which caches the result for some given input string.
I disable the cache it in case of using global or sticky, since the result can change depending on lastIndex and caching likely wouldn't help those patterns.
After experimentation I decided on size 8, because there were rapidly diminishing returns at size 16 and at size 4 I saw a big increase in cache misses.
I tried dynamic sizing as well, but megamorphic cases would quickly max out the cache and the polymorphic cases didn't seem to get much benefit above size 8, so it seemed better to avoid the overhead of resizing and stick with a fixed sized cache.
Improves perf of angular by about 6%.