Avoid allocating Regex when using static methods (#496)
authorStephen Toub <stoub@microsoft.com>
Wed, 4 Dec 2019 22:02:08 +0000 (17:02 -0500)
committerGitHub <noreply@github.com>
Wed, 4 Dec 2019 22:02:08 +0000 (17:02 -0500)
commitb2073bd41e7ba0606000e5950e3d960d1d2eb36d
tree84579aeb22f646ced0f60f6ea837b73a11e4733d
parent46da95eb75c052c828d67d14e46083e7ac2286b1
Avoid allocating Regex when using static methods (#496)

* Avoid allocating Regex when using static methods

Regex supports a cache that's meant to be used for the static methods, e.g. the static Regex.IsMatch.  However, currently that cache isn't caching the actual Regex class, but rather a sub object that stores some of the state from the Regex and then is used to rehydrate a new Regex instance.  This means we allocate a new Regex object when these static methods are used, even if the data is found in the cache.  This means an operation like the static Regex.IsMatch is never allocation-free.  There's also weirdness around this caching, in that when a new Regex instance is constructed, it checks the cache (paying the relevant lookup costs) even though it doesn't add back to the cache, so the only way it would ever find something in the cache is if the same set of inputs (e.g. pattern, options, timeout, etc.) are used with both the Regex ctor and with the static methods, where the static methods would populate the cache that's then consulted by the ctor.  This adds unnecessary expense on the common path for a very uncommon situation; it also complicates the code non-trivially.

This commit changes things to cleanly separate the cache from Regex, and to actually cache the Regex instance itself.

* Address PR feedback
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Cache.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Match.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Replace.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Split.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.Timeout.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Regex.cs
src/libraries/System.Text.RegularExpressions/tests/Regex.Cache.Tests.cs