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

Kb.*_*Kb. 110 .net c# asp.net string performance

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

有谁知道String.Contains方法是否比String.IndexOf方法表现更好?

    // 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);
Run Code Online (Sandbox Code Playgroud)

有趣的事实

Chr*_*s S 167

Contains来电IndexOf:

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

哪些调用CompareInfo.IndexOf最终使用CLR实现.

如果你想看看如何在CLR中比较字符串,这将显示(查找CaseInsensitiveCompHelper).

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

因此,使用来自kernel32.dll的FindNLSString(反射器的强大功能IndexOf)IndexOf直接进行字符串搜索会稍微快一些(理论上).

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

  • 我的答案是7年,基于.NET 2框架.版本4`IndexOf()`确实使用`StringComparison.CurrentCulture`和`Contains()`使用`StringComparison.Ordinal`这将更快.但实际上我们所谈论的速度差异很小 - 关键是一个调用另一个,如果你不需要索引,则Contains更具可读性.换句话说,不用担心. (51认同)
  • 这个答案远非正确,只需看看http://stackoverflow.com/posts/498880/revisions的解释 (3认同)
  • 今天在 1.3 GB 文本文件上尝试过。其中,每一行都会检查是否存在“@”字符。对 Contains/IndexOf 进行了 17.000.000 次调用。结果:所有 Contains() 调用需要 12.5 秒,所有 IndexOf() 调用需要 2.5 秒。=> IndexOf 执行速度快 5 倍!!(.Net 4.8) (2认同)

Gon*_*ero 20

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

  • 吮吸老板是我们......?:D你是对的,与服务http请求所花费的时间相比,搜索一个短字符串,一次,并不重要. (4认同)

ggf*_*416 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完全相同的性能,但它更短并且使你的意图清晰.

  • .NET 4.0的变化在RTM出现之前显然已经恢复了,所以我不会太依赖那篇文章http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-在最BCL-在净4-0贾斯汀-VAN-patten.aspx (2认同)

mag*_*nes 7

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

 if("=,<=,=>,<>,<,>,!=,==,".IndexOf(tmps)>=0) {
Run Code Online (Sandbox Code Playgroud)

 if("=,<=,=>,<>,<,>,!=,==,".Contains(tmps)) {
Run Code Online (Sandbox Code Playgroud)

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

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

  • IndexOf 533ms.
  • 包含266ms.

: - /

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

  • 你忘了使用'StringComparison.Ordinal' (3认同)

Bri*_*sen 6

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

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

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


And*_*rry 6

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

.net框架有一个很好的秒表实现--System.Diagnostics.Stopwatch

  • @JeremyThompson 重复“暂停调试”方法 10 次,你就得到了一个分析器 (2认同)