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

我有一个大约2000个字符的字符串缓冲区,需要检查缓冲区是否包含特定的字符串。
将在 ASP.NET 2.0 webapp 中为每个 webrequest 进行检查。 < br/>

有人知道 字符串。包含方法是否比 方法表现得更好吗?

    // 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);

有趣的事实

127046 次浏览

使用基准库(如 this recent foray from Jon Skeet)来度量它。

买者自慎

作为所有(微观)性能问题,这取决于您正在使用的软件版本、所检查的数据的细节以及围绕调用的代码。

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

从一点点阅读,似乎在引擎盖下的字符串。包含简单调用 String 的方法。IndexOf.区别在于 String。包含返回一个布尔值。IndexOf 返回一个整数(- 1) ,表示未找到子字符串。

我建议编写一个有100,000个左右迭代的小测试,自己看看。如果要我猜,我会说 IndexOf 可能稍微快一点,但就像我说的,它只是一个猜测。

Jeff Atwood 在 他的博客上有一篇关于字符串的好文章,它更多的是关于连接,尽管如此可能还是有帮助的。

通过使用反射器,您可以看到,包含是使用 IndexOf 实现的。

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

因此,与直接调用 IndexOf 相比,Contain 可能稍慢一些,但我怀疑它对实际性能有什么重要意义。

Contains呼叫 IndexOf:

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

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

如果您想了解如何在 CLR 这个会告诉你中比较字符串(请查看 个案不敏感的电脑辅助工具)。

IndexOf(string)没有选项,而且 Contains()使用序号比较(一个字节一个字节的比较,而不是尝试执行智能比较,例如 e 和 é)。

So IndexOf will be marginally faster (in theory) as IndexOf goes straight to a string search using FindNLSString from kernel32.dll (the power of reflector!).

更新为。NET 4.0 -< em > IndexOf 不再使用序号比较,因此包含可以更快。请看下面的评论。

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

The .net framework has an excellent stopwatch implementation - 系统,诊断,秒表

包含(s2)比 IndexOf (s2)快很多倍(在我的计算机中是10倍) ,因为包含使用 Stringratio。序数,比默认情况下 IndexOf 执行的区分区域性搜索更快(但在。4.0 http://davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx).

包含的性能与 IndexOf (s2,String 比较)完全相同。在我的测试中,常规) > = 0,但是它更短,并且表明了你的意图。

作为一个更新,我已经做了一些测试,并提供您的输入字符串相当大,然后并行正则表达式是最快的 C # 方法,我发现(提供您有一个以上的核心,我想)

获取匹配的总量,例如-

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

希望这个能帮上忙!

我正在运行一个真实的案例(在一个合成基准的对立面)

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

VS

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

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

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

  • 533ms 的索引。
  • 包含266毫秒。

:-/

net framework 4.0 (updated as for 13-02-2012)

对于仍在阅读本文的读者来说,indexOf ()可能会在大多数企业系统上表现得更好,因为 include ()与 IE 不兼容!

今天在1.3 GB 的文本文件上试过了。在其他行中,每一行都检查是否存在“@”字符。17.000.000次调用包含/IndexOf。结果: 对于所有包含(’@’)调用,为12.5秒; 对于所有 IndexOf (’@’)调用,为2.5秒。= > IndexOf 执行速度快5倍! !(.净值4.8)