C#LINQ First()比ToArray()[0]快吗?

ret*_*ide 19 c# linq

我正在进行测试.

看起来像:

方法1)

List<int> = new List<int>{1,2,4, .....} //assume 1000k
var  result ErrorCodes.Where(x => ReturnedErrorCodes.Contains(x)).First();
Run Code Online (Sandbox Code Playgroud)

方法2)

List<int> = new List<int>{1,2,4, .....} //assume 1000k
var  result = ErrorCodes.Where(x => ReturnedErrorCodes.Contains(x)).ToArray()[0];
Run Code Online (Sandbox Code Playgroud)

为什么方法2与方法1相比是如此之慢?

Eri*_*ert 60

你有一个包含一千个硬币的罐子,其中许多是硬币.你想要一毛钱.以下是解决问题的两种方法:

  1. 将硬币从罐子里拉出来,一次一个,直到你得到一毛钱.现在你有一毛钱.

  2. 将硬币从罐子里拉出来,一次一个,把硬币放在另一个罐子里.如果那个罐子太小,可以将它们一次一个地移动到一个更大的罐子里.继续这样做,直到你在最后一个罐子里有所有硬币.那个罐子可能太大了.制造一个足够大的罐子来容纳那么多硬币,然后将硬币一次一个地移动到新的罐子里.现在开始从那个罐子里拿出硬币.取出第一个.现在你有一毛钱.

现在很清楚为什么方法1比方法2快很多?

  • 好的,可以通过它来进行类比(但调整大小不会使用块复制吗?不是这会改变性能配置文件; p) (4认同)

Mar*_*ell 46

嗯...因为你正在创建一个额外的数组(而不仅仅是使用迭代器).第一种方法在第一次匹配后停止(Where是非缓冲的流API).第二个将所有匹配加载到一个数组中(可能有几个重新调整大小),然后获取第一个项目.

作为旁注; 你可以创造无限的序列; 第一种方法仍然可行,第二种方法将永远运行(或爆炸).

它也可能是:

var  result ErrorCodes.First(x => ReturnedErrorCodes.Contains(x));
Run Code Online (Sandbox Code Playgroud)

(这不会让它变得更快,但也许更容易阅读)

  • @KeithS - 这取决于无限序列是否全部被`Where`排除,因此变为永无止境但永不屈服.或者实际上,任何*理智*有限数量的匹配和无限数量的"未命中". (2认同)