LINQ 与 foreach 迭代器块的 C# 性能
1)它们生成相同的字节码吗?
2)如果不是,在某些情况下使用其中一种比另一种有什么好处吗?
// LINQ select statement
return from item in collection
select item.Property;
// foreach in an iterator block
foreach (item in collection)
yield return item.Property;
1) Do these generate the same byte code?
2) If not, is there any gain in using one over the other in certain circumstances?
// LINQ select statement
return from item in collection
select item.Property;
// foreach in an iterator block
foreach (item in collection)
yield return item.Property;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它们不会生成相同的代码,但归结为相同的事情,您会得到一个实现
IEnumerable
的对象。不同之处在于 linq 从其库中提供迭代器(在本例中最有可能使用WhereSelectArrayIterator
或WhereSelectListIterator
),而在第二个示例中,您自己生成一个迭代器块来剖析收藏。迭代器块方法始终通过编译器魔法编译为实现IEnumerable
的单独类,您看不到该类,但在调用迭代器块方法时隐式实例化该类。就性能而言,#1 对于可索引集合来说应该稍微(但只是稍微)快一些,因为当您循环生成的
IEnumerable
时,您可以直接从 foreach 进入优化的 linq 迭代器中的集合检索。在示例 #2 中,您从 foreach 进入迭代器块的 foreach,然后从那里进入集合检索,您的性能主要取决于编译器在优化收益逻辑方面的智能程度。无论如何,我认为对于任何复杂的集合机制,检索的成本都会边缘化这种差异。就
恕我直言,我总是会选择#1,如果没有别的办法的话,它可以让我不必编写一个单独的方法来进行迭代。
They don't generate the same code but boil down to the same thing, you get an object implementing
IEnumerable<typeof(Property)>
. The difference is that linq provides iterator from its library (in this case most likely by usingWhereSelectArrayIterator
orWhereSelectListIterator
) whereas in the second example you yourself generate an iterator block that dissects a collection. An iterator block method is always, by ways of compiler magic, compiled as a separate class implementingIEnumerable<typeof(yield)>
which you don't see but instantiate implicitly when you call iterator block method.Performance wise, #1 should be slightly (but just slightly) faster for indexable collections because when you loop through the resulting
IEnumerable
you go directly from your foreach into collection retrieval in an optimized linq iterator. In example #2 you go from foreach into your iterator block's foreach and from there into collection retrieval and your performance depends mostly on how smart the compiler is at optimizing yield logic. In any case I would imagine that for any complex collection mechanism the cost of retrieval marginalizes this difference.IMHO, I would always go with #1, if nothing else it saves me from having to write a separate method just for iterating.
不,它们不会生成相同的字节代码。第一个返回框架中预先存在的类。第二个返回编译器生成的状态机,该状态机返回集合中的项目。该状态机与框架中已经存在的类非常相似。
我怀疑两者之间的性能差异很大。两者最终都在做非常相似的事情。
No they don't generate the same byte code. The first one returns a pre-existing class in the framework. The second one returns a compiler generated state machine that returns the items from the collection. That state machine is very similar to the class that exists in the framework already.
I doubt there's much performance difference between the two. Both are doing very similar things in the end.