IndexOf(char)vs Contains(字符串)的性能,用于检查字符串中是否存在字符

时间:2015-02-02 14:27:26

标签: c# string contains indexof

我想知道string.IndexOf(char)是否比string.Contains(string)更快。意图是检查字符串中是否存在单个字符。我知道根据要求我应该使用string.Contains(string),但这不是这个问题的重点。我试图反编译mscorlib.dll以试图比较它们的实现,但我找不到string.IndexOf(char)的实现,因为它是在CLR本身内实现的。 string.Contains(string)的实施看起来非常“沉重”。

3 个答案:

答案 0 :(得分:3)

试试看

  String source = new String('a', 10000000) + "b" + new String('c', 10000000);

  Stopwatch sw = new Stopwatch();

  sw.Start();

  // Just an estimation
  int result = source.IndexOf('b');
  // int result = source.IndexOf("b");
  // Boolean result = source.Contains("b");
  // Boolean result = source.Contains('b');

  sw.Stop();

  int time = sw.ElapsedMilliseconds;

在我的工作站(i5 3.2 GHz,.Net 5.0 64位)Char需要 10 ms ,{{1}需要 38 ms }

编辑:效果的结果是

String

所以 IndexOf(Char) 10 -- Fastest IndexOf(String) 38 Contains(Char) 100 -- Slowest Contains(String) 41 IndexOf(String)大致相同

答案 1 :(得分:1)

mscorlib.dll的源代码在Microsoft Reference Source上可用(并且在原始帖子发布时已提供)。您可以在String类中看到,其中Contains(string)是包装器

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

围绕IndexOf函数,该函数正在使用外部InternalFindNLSStringEx函数,该函数必须非常快。但由于明显的原因,没有extern IndexOf(char)函数那么快。 这解释了为什么IndexOf(string)Contains(string)的计算速度几乎相同。但是要小心,因为我认为在CLR中它使用某种缓存,所以一个函数的速度取决于调用它的顺序-在另一个函数之前或之后。

这个问题在原始帖子中没有出现,但是正如上面的人提到的那样,我们还要看看Contains<char>,它是Enumerable的扩展名:

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
{
    if (comparer == null) comparer = EqualityComparer<TSource>.Default;
    if (source == null) throw Error.ArgumentNull("source");
    foreach (TSource element in source)
        if (comparer.Equals(element, value)) return true;
    return false;
}

因此,它将按顺序在每个元素上调用Equals。这很简洁,可以使用自定义比较器,但是使用IndexOf(char)会更快。

答案 2 :(得分:0)

  1. 你应该写一个小基准来找出答案。
  2. 我预测这个结果:因为IndexOf(char)是一个简单的循环而且 Contains()(和IndexOf(string))通常是两个嵌套循环, 前者会更快。