我想知道string.IndexOf(char)
是否比string.Contains(string)
更快。意图是检查字符串中是否存在单个字符。我知道根据要求我应该使用string.Contains(string)
,但这不是这个问题的重点。我试图反编译mscorlib.dll以试图比较它们的实现,但我找不到string.IndexOf(char)
的实现,因为它是在CLR本身内实现的。 string.Contains(string)
的实施看起来非常“沉重”。
答案 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)
IndexOf(char)
是一个简单的循环而且
Contains()
(和IndexOf(string)
)通常是两个嵌套循环,
前者会更快。