【问题标题】:Performance of IndexOf(char) vs Contains(string) for checking the presence of a character in a stringIndexOf(char) 与 Contains(string) 的性能检查字符串中是否存在字符
【发布时间】:2015-02-02 14:27:26
【问题描述】:

我想知道

string.IndexOf(char) 

string.Contains(string) 

目的是检查string 中是否存在单个字符。我知道根据要求我应该使用string.Contains(string) 但这不是这个问题的重点。我确实尝试 disassemble mscorlib.dll 以尝试比较它们的实现,但我找不到

的实现
 string.IndexOf(char)

因为它是在 CLR 本身中实现的。实现

 string.Contains(string)

虽然看起来很沉重

【问题讨论】:

标签: c# string performance contains indexof


【解决方案1】:

只是测试看看

  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 毫秒String 大约需要 38 毫秒

编辑:性能的结果是

  IndexOf(Char)     10 -- Fastest
  IndexOf(String)   38 
  Contains(Char)   100 -- Slowest
  Contains(String)  41

所以IndexOf(String)Contains(String) 大致相同

【讨论】:

  • Contains() 呢?
【解决方案2】:

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) 的计算速度几乎相同。但是要小心你的 becnhmarks,因为在 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) 会更快。

【讨论】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2013-01-23
      • 2015-10-27
      相关资源
      最近更新 更多