采用哪一种方法
List<T>.IndexOf()
和List<T>.FindIndex()
在处理时间方面更高效?
本例中
T
的类型是 String
。
IndexOf
执行 for 循环,使用正在搜索的对象的 Equals
实现来查找匹配项。 FindIndex
也执行 for 循环,但评估 Predicate
来检查是否匹配。
它们都归结为一个 for 循环。虽然它们在技术上都具有
O(n)
设计,但在 FindIndex
中使用委托会产生一些开销。 性能上的差异可以在Denis19901的回答中看到。以下是一些 MSDN 摘录:
List<T>.IndexOf Method (T)
:
该方法执行线性搜索;因此,该方法是一个 O(n) 操作,其中 n 是
。Count
List<T>.FindIndex Method (Predicate<T>)
:
该方法执行线性搜索;因此,该方法是一个 O(n) 操作,其中 n 是
。Count
也就是说,这两个函数的使用方式会有很大不同。前者假设您有列表中的一个对象,您只需要知道它在列表中存在的索引(如果有)。
后者假设您知道有关对象的一些条件,并且您想要找到列表中对象与该条件匹配的第一个索引。可能有多个匹配项,但该方法返回第一个匹配项。
Cᴏʀʏ 表示,如果有的话,性能差异可以忽略不计。因为我的直觉告诉我使用委托总是会变慢,所以我决定对其进行测试。
使用DotNetBenchMark和以下代码进行测试:
[MemoryDiagnoser]
public class Bench
{
byte[] buffer;
public Bench()
{
buffer = new byte[1024];
}
[Benchmark]
public void FindIndex()
{
int index = Array.FindIndex(buffer, x => x == byte.MaxValue);
}
[Benchmark]
public void IndexOf()
{
int index = Array.IndexOf(buffer, byte.MaxValue);
}
}
性能差异似乎不容忽视,因为速度慢了 10 倍以上。
即使在数组的第 16 个元素匹配的情况下,IndexOf 仍然比 FindIndex 快两倍以上