mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Improve the caching when creating new Regex instances (#10657)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
@@ -9,10 +10,8 @@ using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Internal.Host;
|
||||
using System.Management.Automation.Language;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
@@ -1347,35 +1346,37 @@ namespace System.Management.Automation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache regular expressions...
|
||||
/// Cache regular expressions.
|
||||
/// </summary>
|
||||
/// <param name="patternString">The string to find the pattern for.</param>
|
||||
/// <param name="options">The options used to create the regex...</param>
|
||||
/// <returns>A case-insensitive Regex...</returns>
|
||||
/// <param name="options">The options used to create the regex.</param>
|
||||
/// <returns>New or cached Regex.</returns>
|
||||
internal static Regex NewRegex(string patternString, RegexOptions options)
|
||||
{
|
||||
if (options != RegexOptions.IgnoreCase)
|
||||
return new Regex(patternString, options);
|
||||
|
||||
lock (s_regexCache)
|
||||
var subordinateRegexCache = s_regexCache.GetOrAdd(options, s_subordinateRegexCacheCreationDelegate);
|
||||
if (subordinateRegexCache.TryGetValue(patternString, out Regex result))
|
||||
{
|
||||
Regex result;
|
||||
if (s_regexCache.TryGetValue(patternString, out result))
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (subordinateRegexCache.Count > MaxRegexCache)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_regexCache.Count > MaxRegexCache)
|
||||
s_regexCache.Clear();
|
||||
Regex re = new Regex(patternString, RegexOptions.IgnoreCase);
|
||||
s_regexCache.Add(patternString, re);
|
||||
return re;
|
||||
// TODO: it would be useful to get a notice (in telemetry?) if the cache is full.
|
||||
subordinateRegexCache.Clear();
|
||||
}
|
||||
|
||||
var regex = new Regex(patternString, options);
|
||||
return subordinateRegexCache.GetOrAdd(patternString, regex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, Regex> s_regexCache = new Dictionary<string, Regex>();
|
||||
private static readonly ConcurrentDictionary<RegexOptions, ConcurrentDictionary<string, Regex>> s_regexCache =
|
||||
new ConcurrentDictionary<RegexOptions, ConcurrentDictionary<string, Regex>>();
|
||||
|
||||
private static readonly Func<RegexOptions, ConcurrentDictionary<string, Regex>> s_subordinateRegexCacheCreationDelegate =
|
||||
key => new ConcurrentDictionary<string, Regex>(StringComparer.Ordinal);
|
||||
|
||||
private const int MaxRegexCache = 1000;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -909,7 +909,7 @@ namespace System.Management.Automation
|
||||
WildcardPatternParser.Parse(wildcardPattern, parser);
|
||||
try
|
||||
{
|
||||
return new Regex(parser._regexPattern.ToString(), parser._regexOptions);
|
||||
return ParserOps.NewRegex(parser._regexPattern.ToString(), parser._regexOptions);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
@@ -1258,7 +1258,7 @@ namespace System.Management.Automation
|
||||
protected override void EndBracketExpression()
|
||||
{
|
||||
_bracketExpressionBuilder.Append(']');
|
||||
Regex regex = new Regex(_bracketExpressionBuilder.ToString(), _regexOptions);
|
||||
Regex regex = ParserOps.NewRegex(_bracketExpressionBuilder.ToString(), _regexOptions);
|
||||
_patternElements.Add(new BracketExpressionElement(regex));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user