首页 > 解决方案 > 使用 IsMatch 时的 REGEX 性能问题

问题描述

我有以下用于执行重定向的正则表达式

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

有什么解决方案可以优化上述内容吗?

谢谢

标签: c#

解决方案


我会尝试创建一个实际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;

推荐阅读