【问题标题】:difference between linq.first() vs array[0] [duplicate]linq.first() 与数组 [0] 之间的区别 [重复]
【发布时间】:2014-09-01 22:25:05
【问题描述】:

我想知道在 list.first() 和 list[0] 的背后发生了什么,哪个表现更好。

例如哪个更快?

for(int i = 0; i < 999999999999... i++)
{
    str.Split(';').First() vs. str.Split(';')[0]

    list.Where(x => x > 1).First() vs. list.Where(x => x > 1).ToList()[0]
}

抱歉,如果有重复的问题

【问题讨论】:

  • list.Where(x =&gt; x &gt; 1).First() vs list.Where(x =&gt; x &gt; 1).ToList()[0] 第一个解决方案具有更好的性能 - 第二个将枚举整个序列,而第一个解决方案将在第一个元素处停止。
  • 为什么不试试呢?执行你自己的基准测试,我不完全确定潜在的差异,但我想First() 是延迟执行
  • @Marwie - 这不是一个完整的副本,因为它没有回答第一次比较
  • @Marwie - 因为您要添加转换操作,所以一切都不同

标签: c#


【解决方案1】:

哪个表现更好?数组访问器,因为它不需要将方法放入堆栈,也不必执行First 方法来最终访问数组访问器。

正如Reference Source of Enumerable 所示,First() 实际上是:

IList<TSource> list = source as IList<TSource>;
if (list != null) {
    if (list.Count > 0) return list[0];
}

所以它没有做任何其他事情,只是需要更多的步骤才能到达那里。

第二部分(list.Where(x =&gt; x &gt; 1).First() vs. list.Where(x =&gt; x &gt; 1).ToList()[0]):

Where 返回一个IEnumerable,它不是IList,因此它不适用于First 方法的第一部分,而是第二部分:

using (IEnumerator<TSource> e = source.GetEnumerator()) {
    if (e.MoveNext()) return e.Current;
}

这将逐个遍历每个项目,直到获得所需的索引。在这种情况下0,所以它很快就会到达那里非常。另一个调用ToList 的效率总是较低,因为它必须创建一个新对象并将所有项目放在那里才能获得第一个。第一次调用肯定更快。

【讨论】:

  • @PatrickHofman .First vs .ToList()[0]
  • @Rawling 查看我的评论或打开 Marwie 链接。
  • @Rawling 好吧,我的错。
【解决方案2】:

性能的简单压缩http://pastebin.com/bScgyDaM

str.Split(';').First(); :                        529103
str.Split(';')[0]; :                             246753
list.Where(x => x == "a").First(); :              98590
list.Where(x => x == "a").ToList()[0]; :         230858

第一个 vs [0] 如果您有简单的数组,则速度更快的是 [0],因为它只计算内存中的加法器。 但如果你与其他人结合使用更快的 LINQ 命令是 First()。例如 Where().First() 搜索直到找到第一个元素。 Where().ToList()[0] 查找所有元素然后转换为列表并进行简单计算。

另一件事是 Where() 是一个延迟方法。在枚举结果中的项目之前,不会执行仅包含延迟方法的查询。 所以你可以

list.Where( x => x>12);
list.add(10);
list.add(13);
foreach (int item in list)
{
   Console.WriteLine(item); 
}

13 将附加到结果中,但 10 不附加,因为 10 和 13 首先添加到列表中,后来搜索了列表。

如果您想了解更多关于 Linq 的信息,可以阅读 Joseph Rattz 和 Adam Freeman 所著的《Pro LINQ》一书http://www.apress.com/9781430226536

【讨论】:

    【解决方案3】:

    这些之间没有显着差异,你会得到几乎相同的结果:

     str.Split(';').First() vs. str.Split(';')[0]
    

    对于您的第二个比较,这里您只询问第一个元素

    list.Where(x => x > 1).First()
    

    所以只要WhereIterator 返回一个项目,它就完成了。但是在第二个中,您将所有结果放入列表中,然后使用 indexer 获取第一项,因此它会更慢。

    【讨论】:

      【解决方案4】:
      • list.Where(x =&gt; x &gt; 1).First() vs. list.Where(x =&gt; x &gt; 1).ToList()[0]

        First() 应用于 Enumerable 时应该更快,因为 延期执行。在您的情况下,结果将尽快返回 因为您的清单中有一项符合条件 哪里(x => x > 1).

        在第二个示例中,您的初始列表必须完全枚举, 所有项符合条件的项目将被放入一个临时列表中,您将使用数组访问器获得其中的第一项。

      • str.Split(';').First() vs. str.Split(';')[0]

        在这种情况下,Split() 方法已经返回了一个数组。数组访问器可能稍微快一些,但在大多数情况下性能提升可以忽略不计。

      【讨论】:

        猜你喜欢
        • 2018-12-15
        • 1970-01-01
        • 2020-04-11
        • 2013-06-27
        • 2011-12-01
        • 1970-01-01
        • 2019-03-05
        • 2012-02-08
        • 2013-05-17
        相关资源
        最近更新 更多