C#性能的LINQ与foreach迭代器块 [英] C# Performance of LINQ vs. foreach iterator block

查看:162
本文介绍了C#性能的LINQ与foreach迭代器块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1)这些产生了相同的字节码吗?

2)如果不是,在某些情况下使用某个字节码有什么好处吗?

  // LINQ select语句
从集合中的元素返回
select item.Property;

//在迭代器块中foreach
foreach(集合中的元素)
yield return item.Property;


解决方案


  1. 不要生成相同的代码,但要归结为相同的事情,你会得到一个实现 IEnumerable< typeof(Property)> 的对象。不同之处在于linq提供了它的库中的迭代器(在这种情况下很可能通过使用 WhereSelectArrayIterator WhereSelectListIterator ),第二个例子,你自己生成一个迭代器块来剖析一个集合。一个迭代器块的方法总是通过编译器魔术的方式,编译为一个单独的类实现 IEnumerable< typeof(yield)> ,你看不到,但隐式地实例化你调用迭代器块的方法。性能方面,对于可索引集合,#1应该略微(但略微)更快,因为当你遍历结果 IEnumerable

  2. 时, / code>你直接从你的foreach进入一个优化的linq迭代器的集合检索。在示例2中,您将从foreach进入到您的迭代器块的foreach中,并从那里进入到集合检索中,而您的性能主要取决于编译器在优化yield yield逻辑时的智能程度。在任何情况下,我都会想象,对于任何复杂的收集机制来说,检索的成本都会使这种差异受到限制。

总是会与#1,如果没有别的,它可以节省我不得不写一个单独的方法只是迭代。

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;

解决方案

  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 using WhereSelectArrayIterator or WhereSelectListIterator) 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 implementing IEnumerable<typeof(yield)> which you don't see but instantiate implicitly when you call iterator block method.

  2. 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.

这篇关于C#性能的LINQ与foreach迭代器块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆