String.Contains()比String.IndexOf()更快吗?

时间:2009-01-31 11:42:37

标签: c# .net asp.net performance string

我有一个大约2000个字符的字符串缓冲区,如果它包含特定字符串,则需要检查缓冲区 将针对每个webrequest在ASP.NET 2.0 webapp中进行检查。

有人知道String.Contains method的效果是否优于String.IndexOf method

    // 2000 characters in s1, search token in s2
    string s1 = "Many characters. The quick brown fox jumps over the lazy dog"; 
    string s2 = "fox";
    bool b;
    b = s1.Contains(s2);
    int i;
    i = s1.IndexOf(s2);

Fun fact

11 个答案:

答案 0 :(得分:159)

Contains来电IndexOf

public bool Contains(string value)
{
    return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}

哪个调用CompareInfo.IndexOf,最终使用CLR实现。

如果你想看看如何在CLR this will show you中比较字符串(查找 CaseInsensitiveCompHelper )。

IndexOf(string)没有选项,Contains()使用序数比较(逐字节比较,而不是尝试执行智能比较,例如,e与é)。

所以IndexOf稍微快一点(理论上)因为IndexOf直接使用来自kernel32.dll的FindNLSString(反射器的力量!)进行字符串搜索。

针对.NET 4.0进行了更新 - IndexOf不再使用Ordinal Comparison,因此Contains可以更快。请参阅下面的评论。

答案 1 :(得分:20)

可能根本不重要。阅读关于Coding Horror的这篇文章;):http://www.codinghorror.com/blog/archives/001218.html

答案 2 :(得分:11)

包含(s2)很多次(在我的计算机中10次)比IndexOf(s2)快,因为Contains使用的StringComparison.Ordinal比IndexOf默认执行的文化敏感搜索更快(但可能会在.net中更改) 4.0 http://davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx)。

在我的测试中,Contains与IndexOf(s2,StringComparison.Ordinal)> = 0具有完全相同的性能,但它更短并且使你的意图清晰。

答案 3 :(得分:7)

我正在运行一个真实案例(与合成基准相反)

 if("=,<=,=>,<>,<,>,!=,==,".IndexOf(tmps)>=0) {

 if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {

它是我系统的重要组成部分,执行时间为131,953次(感谢DotTrace)。

然而令人震惊的惊喜,结果与预期相反

  • IndexOf 533ms。
  • 包含266ms。

: - /

net framework 4.0(更新时间为2012年2月13日)

答案 4 :(得分:6)

通过使用Reflector,您可以看到,Contains是使用IndexOf实现的。这是实施。

public bool Contains(string value)
{
   return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}

所以Contains可能比直接调用IndexOf慢一点,但我怀疑它对实际性能有什么意义。

答案 5 :(得分:5)

如果您真的想要微观优化代码,那么最好的方法就是始终进行基准测试。

.net框架具有出色的秒表实现 - System.Diagnostics.Stopwatch

答案 6 :(得分:3)

从一点点阅读开始,看起来String.Contains方法只是调用String.IndexOf。区别在于String.Contains返回一个布尔值,而String.IndexOf返回一个整数,其中(-1)表示未找到子字符串。

我建议用100,000次左右的迭代编写一个小测试,亲自看看。如果我猜测,我会说IndexOf可能稍微快一些,但就像我说的那样只是猜测。

杰夫阿特伍德在his blog有一篇关于字符串的好文章。它更多的是关于连接,但可能会有所帮助。

答案 7 :(得分:3)

正如对此的更新我一直在做一些测试并且提供输入字符串相当大然后并行Regex是我发现的最快的C#方法(假设你有多个我想象的核心)

获取匹配总数例如 -

needles.AsParallel ( ).Sum ( l => Regex.IsMatch ( haystack , Regex.Escape ( l ) ) ? 1 : 0 );

希望这有帮助!

答案 8 :(得分:2)

使用基准库,例如this recent foray from Jon Skeet来衡量它。

Caveat Emptor

作为所有(微观)性能问题,这取决于您使用的软件版本,检查数据的详细信息以及呼叫周围的代码。

作为所有(微观)性能问题,第一步必须是获得易于维护的运行版本。然后,基准测试,分析和调整可以应用于测量的瓶颈,而不是猜测。

答案 9 :(得分:1)

今天在1.3 GB的文本文件中进行了尝试。除其他外,检查每一行是否存在“ @”字符。对Contains / IndexOf进行了17.000.000次调用。结果:所有Contains('@')调用为12.5秒,所有IndexOf('@')调用为2.5秒。 => IndexOf的执行速度提高了5倍!! (.Net 4.8)

答案 10 :(得分:-6)

For anyone still reading this, indexOf() will probably perform better on most enterprise systems, as contains() is not compatible with IE!