Skip to content

Conversation

@MikeHolman
Copy link
Contributor

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%.


if (useCache && cachedValue == input)
{
return JavascriptBoolean::ToVar(cache[cacheIndex].result, scriptContext);
Copy link
Collaborator

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?

Copy link
Contributor Author

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;
Copy link
Contributor

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?

Copy link
Contributor Author

@MikeHolman MikeHolman Sep 25, 2017

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.

const bool isGlobal = pattern->IsGlobal();
const bool isSticky = pattern->IsSticky();

if (useCache && cacheHit)
Copy link
Collaborator

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.

Copy link
Collaborator

@agarwal-sandeep agarwal-sandeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@chakrabot chakrabot merged commit 94491e8 into chakra-core:master Sep 26, 2017
chakrabot pushed a commit that referenced this pull request Sep 26, 2017
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%.
boingoing added a commit to boingoing/ChakraCore that referenced this pull request Jan 27, 2018
…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
chakrabot pushed a commit that referenced this pull request Jan 30, 2018
…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
chakrabot pushed a commit that referenced this pull request Jan 30, 2018
…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
chakrabot pushed a commit that referenced this pull request Jan 30, 2018
…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
chakrabot pushed a commit to nodejs/node-chakracore that referenced this pull request Jan 30, 2018
[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>
chakrabot pushed a commit to nodejs/node-chakracore that referenced this pull request Jan 30, 2018
[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>
kfarnung pushed a commit to kfarnung/node-chakracore that referenced this pull request Feb 1, 2018
[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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants