C# RegEx.IsMatch()与String.ToUpper()的性能比较

C# RegEx.IsMatch()与String.ToUpper()的性能比较,c#,regex,string,C#,Regex,String,由于.NET中没有不区分大小写的string.Contains()(但是存在一个不区分大小写的string.Equals()版本,这让我感到困惑,但我离题了),使用RegEx.IsMatch()与使用string.ToUpper().Contains()之间的性能差异是什么 例如: string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion"; bool containsString = RegEx.IsMatch(test

由于.NET中没有不区分大小写的
string.Contains()
(但是存在一个不区分大小写的
string.Equals()
版本,这让我感到困惑,但我离题了),使用
RegEx.IsMatch()
与使用
string.ToUpper().Contains()
之间的性能差异是什么

例如:

string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion";

bool containsString = RegEx.IsMatch(testString, "string", RegexOptions.IgnoreCase);
bool containsStringRegEx = testString.ToUpper().Contains("STRING");
我一直听说
string.ToUpper()
是一个非常昂贵的调用,所以当我想进行
string.Contains()
比较时,我会避免使用它,但是
RegEx.IsMatch()
在性能方面如何比较呢


有没有更有效的方法来进行此类比较?

有另一种版本可能比您建议的两种方法更有效:

string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion";
bool contained = testString.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;
如果需要区分区域性的比较,请使用
CurrentCultureIgnoreCase
而不是
OrdinalingOreCase

这里是一个基准

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();

        string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion";

        sw.Start();
        var re = new Regex("string", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
        for (int i = 0; i < 1000000; i++)
        {
            bool containsString = re.IsMatch(testString);
        }
        sw.Stop();
        Console.WriteLine("RX: " + sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < 1000000; i++)
        {
            bool containsStringRegEx = testString.ToUpper().Contains("STRING");
        }


        sw.Stop();
        Console.WriteLine("Contains: " + sw.ElapsedMilliseconds);

        sw.Restart();
        for (int i = 0; i < 1000000; i++)
        {
            bool containsStringRegEx = testString.IndexOf("STRING", StringComparison.OrdinalIgnoreCase) >= 0 ;
        }


        sw.Stop();
        Console.WriteLine("IndexOf: " + sw.ElapsedMilliseconds);
    }
}
使用系统;
使用系统诊断;
使用System.Text.RegularExpressions;
公共课程
{
公共静态void Main(字符串[]args)
{
秒表sw=新秒表();
string testString=“thisisstringwithinconsistentcapitalization”;
sw.Start();
var re=new Regex(“字符串”,RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
对于(int i=0;i<1000000;i++)
{
bool containsString=re.IsMatch(testString);
}
sw.Stop();
控制台写入线(“接收:+sw.ElapsedMilliseconds);
sw.Restart();
对于(int i=0;i<1000000;i++)
{
bool containsstringex=testString.ToUpper().Contains(“字符串”);
}
sw.Stop();
Console.WriteLine(“包含:“+sw.ElapsedMilliseconds”);
sw.Restart();
对于(int i=0;i<1000000;i++)
{
bool containsStringRegEx=testString.IndexOf(“STRING”,StringComparison.OrdinalIgnoreCase)>=0;
}
sw.Stop();
Console.WriteLine(“IndexOf:+sw.ElapsedMilliseconds”);
}
}
结果是

IndexOf(183ms)>Contains(400ms)>Regex(477ms)


(使用已编译的正则表达式更新输出时间)

根据个人使用正则表达式解析器的经验,我预计
Regex.match
的速度会很慢。但正如许多人所提到的,分析是确定答案的最好方法。我已经解决了与正则表达式解析器相关的性能问题,
toLower
toUpper
从来都没有出现过问题。

您尝试过使用吗?要知道哪一个更快,唯一的方法是同时运行它们并计时。这可能会有帮助:那么
testString.IndexOf(“string”,StringComparison.CurrentCultureIgnoreCase)>=0
?在大多数情况下,避免使用ToLower/ToUpper来处理这些事情。这是不好的做法如果你支持一个有多种语言的全球世界,那么Tupper/ToLower可能会欺骗你。我的PC上的结果:RX:3032包含:385 IndexOf:97(mono下未优化的构建)(PS.我预先编译了Regex)@Ata-你是说它对结果有影响吗?我在所有三个测试中都使用外部
for
循环运行了代码,但上述结果的差异可以忽略不计。哇,我从来没有想到
RegEx
ToUpper().Contains()
慢,我甚至没有想过使用
IndexOf()>=0
来完成任务,更不用说它是目前为止最快的了。谢谢看起来我将在中使用
IndexOf()
future@Saggio-不客气。正则表达式可能比字符串操作慢,但它也更灵活,对于更复杂的解析性能更好,因此使用合适的工具来完成这项工作是一种情况。就个人而言,对于基本的字符串操作,我尽量避免使用正则表达式()