【问题标题】:Efficiency of List<T>.IndexOf() versus List<T>.FindIndex()List<T>.IndexOf() 与 List<T>.FindIndex() 的效率
【发布时间】:2015-11-05 02:17:56
【问题描述】:

哪一种方法

  • List&lt;T&gt;.IndexOf()
  • List&lt;T&gt;.FindIndex()

在处理时间方面效率更高?

此实例中T 的类型为String

【问题讨论】:

标签: c# performance list


【解决方案1】:

IndexOf 执行一个 for 循环,使用正在搜索的对象的 Equals 实现来查找匹配项。 FindIndex 也执行一个 for 循环,但评估 Predicate 以检查匹配。

它们每个都归结为一个 for 循环。虽然它们在技术上都具有O(n) 设计,但在FindIndex 中使用委托会产生一些开销。在Denis19901's answer 中可以看到性能上的差异。以下是一些 MSDN 摘录:

List&lt;T&gt;.IndexOf Method (T)

此方法执行线性搜索;因此,这个方法是一个 O(n) 操作,其中 nCount

List&lt;T&gt;.FindIndex Method (Predicate&lt;T&gt;)

此方法执行线性搜索;因此,这个方法是一个 O(n) 操作,其中 nCount

也就是说,这两个函数的使用方式完全不同。前者假定您有一个来自列表的对象,您只需要知道它存在于列表中(如果有的话)的哪个索引处。

后者假设您知道某个对象的一些标准,并且您希望找到列表中的对象与该标准匹配的第一个索引。可能有多个匹配项,但该方法返回第一个匹配项。

【讨论】:

    【解决方案2】:

    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);
        }
    }
    
    • FindIndex 的平均运行时间为 1,986.2 ns
    • IndexOf 的平均运行时间为 178.4 ns

    似乎性能差异可以忽略不计,因为它慢了 10 倍以上。

    即使在数组的第 16 个元素匹配的情况下,IndexOf 的速度仍然是 FindIndex 的两倍以上

    【讨论】:

    • 感谢您对我的回答的分析和审查。我很乐意修改它。
    • 很高兴能够做出贡献!
    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 2015-11-19
    • 2019-08-27
    • 2019-05-20
    • 2021-11-26
    相关资源
    最近更新 更多