人们已经无数次证明,那yield return
比list
.
但是,当我尝试基准测试时,得到了相反的结果:
Results:
TestYield: Time =1.19 sec
TestList : Time =4.22 sec
在这里,List 慢了 400%。无论大小都会发生这种情况。这是没有意义的。
IEnumerable<int> CreateNumbers() //for yield
{
for (int i = 0; i < Size; i++) yield return i;
}
IEnumerable<int> CreateNumbers() //for list
{
var list = new List<int>();
for (int i = 0; i < Size; i++) list.Add(i);
return list;
}
以下是我使用它们的方式:
foreach (var value in CreateNumbers()) sum += value;
我使用所有正确的基准规则来避免结果冲突,所以这不是问题。
如果你看到底层代码,yield return它是一个状态机可憎,但它更快。为什么?
编辑:所有答案都被复制,确实产量比列表快。
New Results With Size set on constructor:
TestYield: Time =1.001
TestList: Time =1.403
From a 400% slower difference, down to 40% slower difference.
然而,这些见解令人心碎。这意味着所有那些从 1960 年起使用 list 作为默认集合的程序员都是错误的,应该被解雇(解雇),因为他们没有使用最好的工具来解决这种情况(yield)。
答案认为,收益率应该更快,因为它没有实现。
1)我不接受这个逻辑。Yield 背后有内部逻辑,它不是“理论模型”,而是编译器构造。因此,它会在消费时自动实现。我不接受它“没有实现”的论点,因为成本已经在使用时支付。
2)如果船可以走海路,而老妇人不行,你不能要求船“走陆路”。正如你在这里对列表所做的那样。如果一个列表需要具体化,而 yield 不需要,那不是“产量问题”,而是一个“特性”。不应仅仅因为它有更多用途而在测试中惩罚产量。
3)我在这里争论的是,如果您知道整个 SET将被消耗,那么测试的目的是找到“最快的集合”来消耗/返回方法返回的结果。
yield 是否成为从方法返回列表参数的新“事实上的标准”。
Edit2:如果我使用纯内联数组,它会获得与 Yield 相同的性能。
Test 3:
TestYield: Time =0.987
TestArray: Time =0.962
TestList: Time =1.516
int[] CreateNumbers()
{
var list = new int[Size];
for (int i = 0; i < Size; i++) list[i] = i;
return list;
}
因此,yield 会自动内联到数组中。列表不是。
米琪卡哇伊
HUH函数
相关分类