将 IEnumerable 与一项一起使用时,哪个更好:yield return 或 return []?
这是“你可以通过多种方式做到这一点”问题之一。考虑以下代码:
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference referece = new ScriptReference();
referece.Assembly = "FeyenoordEnabled";
referece.Name = "FeyenoordEnabled.PassTextBox.js";
return new ScriptReference[] { referece };
}
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference referece = new ScriptReference();
referece.Assembly = "FeyenoordEnabled";
referece.Name = "FeyenoordEnabled.PassTextBox.js";
yield return referece;
}
我只需要返回一个项目。第一段代码返回一个包含单个项目的数组,第二段代码生成该项目。 什么更好,为什么?
This is one of those "you can do it many ways" questions. Consider the following code:
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference referece = new ScriptReference();
referece.Assembly = "FeyenoordEnabled";
referece.Name = "FeyenoordEnabled.PassTextBox.js";
return new ScriptReference[] { referece };
}
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference referece = new ScriptReference();
referece.Assembly = "FeyenoordEnabled";
referece.Name = "FeyenoordEnabled.PassTextBox.js";
yield return referece;
}
I only need to return one item. The first piece of codes returns an array with a single item and the second one yields the item. What is better and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
yield
是一个非常昂贵的关键字。你告诉编译器要做很多事情。如果性能不是问题,请使用更优雅的代码。但如果性能是一个问题,请坚持使用阵列。根据过去的经验,我可以说,摆脱这种类型的
yield
使用方式给我带来了一些显着的性能提升。但一如既往,分析并找到真正的瓶颈。yield
is a pretty expensive keyword. You are telling the compiler to do a lot. If performance isn't an issue, go with the more elegant code. But if performance is an issue, stick with the array.I can say from past experience that getting rid of this type of
yield
usage has netted me some serious performance gains. But as always, profile and find the real bottlenecks.简介简介简介。这是使用 mono 的 AB 比较:(
启用
-optimize+
编译)yield 版本实例化一个实现
IEnumerable
的类和整个 shebang:注意
我省略了实现枚举器块“匿名”类型
Program/'c__Iterator0'
的 163 行 CIL 代码。在这里查看全部内容: https://gist.github.com/1384014数组版本似乎简单得多:
关于实际运行时性能,PROFILE PROFILE PROFILE!
Profile profile profile. Here is a A-B comparison using mono:
(Compiled with
-optimize+
enabled)The yield version instantiates a class that implements
IEnumerable
and the whole shebang:Note
I left out the 163 lines of CIL code implementing the enumerator block 'anonymous' type
Program/'<UsingYield>c__Iterator0'
. See it all here: https://gist.github.com/1384014The array version seems much simpler:
On the actual runtime performance, PROFILE PROFILE PROFILE!
当您使用创建的数组调用它时,第一个会直接返回。
第二个,由于您使用的是yield,因此它甚至不会执行,直到您开始获取元素(在您的情况下是一个元素)。
所以这实际上取决于你想做什么,但要注意不同的行为。
The first one returns directly when you call it with the array you created it.
The second one, since you are using yield, it wont even execute until you start fetching the elements (well in your case one element).
So it really depends what you want to do, but just be aware different behavior.
使用 Benchmark.NET 进行分析后,很明显,使用数组作为单个值比使用数组更快
收益回报
。使用 .NET Core 3.1.2 x64 Windows 进行测试
After profiling with Benchmark.NET , it is clear that using array for single value is faster than using
yield return
.Tested using .NET Core 3.1.2 x64 Windows