为了账号安全,请及时绑定邮箱和手机立即绑定

使用 IsMatch 时的 REGEX 性能问题

使用 IsMatch 时的 REGEX 性能问题

C#
慕尼黑5688855 2022-01-16 14:43:12
我有以下用于执行重定向的正则表达式string requestedPath = HttpUtility.UrlDecode(this.StripLanguage(currentContext.InputUrl.AbsolutePath));string requestedPathAndQuery = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);string requestedRawUrl = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);string requestedUrl =    HttpUtility.UrlDecode(        string.Concat(            currentContext.InputUrl.Scheme,            "://",            currentContext.InputUrl.Host,            requestedRawUrl));string requestedRawUrlDomainAppended = HttpUtility.UrlDecode(currentContext.InputUrl.AbsoluteUri);string requestedPathWithCulture = HttpUtility.UrlDecode(currentContext.InputUrl.AbsolutePath);                    var finalRequestedURL = string.Empty;finalRequestedURL = Regex.IsMatch(requestedPathAndQuery,matchPattern.Trim(),RegexOptions.IgnoreCase)                    ? requestedPathAndQuery                    : Regex.IsMatch(requestedPath,matchPattern.Trim(),RegexOptions.IgnoreCase)                        ? requestedPath                        : Regex.IsMatch(requestedPathWithCulture,matchPattern.Trim(),RegexOptions.IgnoreCase)                            ? requestedPathWithCulture                            : Regex.IsMatch(requestedRawUrl,matchPattern.Trim(),RegexOptions.IgnoreCase)                                ? requestedRawUrl                                : Regex.IsMatch(requestedUrl,matchPattern.Trim(),RegexOptions.IgnoreCase)                                    ? requestedRawUrlDomainAppended                                    : string.Empty;matchPattern变量是 URL 。示例:(.*)/articles/my-article(.*)应重定向到http://www.google.com正则表达式工作正常,但是当涉及到大量请求时,我们的 CPU 会达到 100%。有什么解决方案可以优化上述内容吗?
查看完整描述

2 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

我会尝试创建一个实际Regex变量并重用它。这应该有助于加快速度。我也可能会建议将三元业务更改为常规的 if/else if/else 语句。我认为它会更具可读性(只是个人意见)。


string requestedPath = HttpUtility.UrlDecode(this.StripLanguage(currentContext.InputUrl.AbsolutePath));

string requestedPathAndQuery = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);

string requestedRawUrl = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);

string requestedUrl =

    HttpUtility.UrlDecode(

        string.Concat(

            currentContext.InputUrl.Scheme,

            "://",

            currentContext.InputUrl.Host,

            requestedRawUrl));


string requestedRawUrlDomainAppended = HttpUtility.UrlDecode(currentContext.InputUrl.AbsoluteUri);

string requestedPathWithCulture = HttpUtility.UrlDecode(currentContext.InputUrl.AbsolutePath);


var regex = new Regex(matchPattern.Trim(), RegexOptions.IgnoreCase);

var finalRequestedURL = regex.IsMatch(requestedPathAndQuery)

                    ? requestedPathAndQuery

                    : regex.IsMatch(requestedPath)

                        ? requestedPath

                        : regex.IsMatch(requestedPathWithCulture)

                            ? requestedPathWithCulture

                            : regex.IsMatch(requestedRawUrl)

                                ? requestedRawUrl

                                : regex.IsMatch(requestedUrl)

                                    ? requestedRawUrlDomainAppended

                                    : string.Empty;

编辑


正如我在上面的评论中指出的那样,有两个相同的字符串,如果您删除其中一个,可以节省比较。


string requestedPath = HttpUtility.UrlDecode(this.StripLanguage(currentContext.InputUrl.AbsolutePath));

string requestedPathAndQuery = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);


// This string is identical to requestPathAndQuery, so I am removing it

// string requestedRawUrl = HttpUtility.UrlDecode(currentContext.InputUrl.PathAndQuery);


string requestedUrl =

    HttpUtility.UrlDecode(

        string.Concat(

            currentContext.InputUrl.Scheme,

            "://",

            currentContext.InputUrl.Host,

            requestedRawUrl));


string requestedRawUrlDomainAppended = HttpUtility.UrlDecode(currentContext.InputUrl.AbsoluteUri);

string requestedPathWithCulture = HttpUtility.UrlDecode(currentContext.InputUrl.AbsolutePath);


var regex = new Regex(matchPattern.Trim(), RegexOptions.IgnoreCase);

var finalRequestedURL = string.Empty;


// You could even add in brackets here to aid readability but this

// helps remove the indententation/nesting that makes the code harder

// to read and follow

if (regex.IsMatch(requestedPathAndQuery)) finalRequestURL = requestedPathAndQuery;

else if(regex.IsMatch(requestedPath)) finalRequestURL = requestedPath;

else if (regex.IsMatch(requestedPathWithCulture)) finalRequestURL = requestedPathWithCulture;

else if (regex.IsMatch(requestedUrl)) finalRequestURL = requestedRawUrlDomainAppended;


查看完整回答
反对 回复 2022-01-16
?
森林海

TA贡献2011条经验 获得超2个赞

正如我在评论中所说,如果您预计只有有限数量的不同模式可以在您的应用程序的生命周期中重用,您可以创建一个静态Dictionary(我认为最好使用并发模式)并缓存此正则表达式并重用它们。


编辑


示例代码:


public class MyHandler

{

    private static ConcurrentDictionary<string, Regex> dict = new ConcurrentDictionary<string, Regex>();


    public void Handle(string urlPattern)

    {

        urlPattern = urlPattern.Trim();

        var regex = dict.GetOrAdd(urlPattern, s => new Regex(urlPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase));

        // use regex

    }

}

还要测试RegexOptions.Compiled选项是否适合您,因为它实际上会使事情变慢


查看完整回答
反对 回复 2022-01-16
  • 2 回答
  • 0 关注
  • 235 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信