将IEnumerable与一个项目一起使用时有什么好处:yield return或return []?

Kee*_*ker 9 .net c# ienumerable yield

这是" 你可以做很多方面 "的问题之一.请考虑以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

我只需要退回一件物品.第一段代码返回一个包含单个项目的数组,第二段代码生成该项目.什么更好,为什么?

Mat*_*eer 8

yield是一个非常昂贵的关键字.你告诉编译器要做很多事情.如果性能不是问题,请使用更优雅的代码.但如果性能是一个问题,坚持使用阵列.

我可以从过去的经验中说,摆脱这种yield用法已经给我带来了一些严重的性能提升.但一如既往,剖析并找到真正的瓶颈.


seh*_*ehe 5

个人档案资料.这是使用mono的AB比较:

public static IEnumerable<int> UsingYield()
{
    yield return 42;
}
public static IEnumerable<int> ReturningArray()
{
    return new []{ 42 };
}
Run Code Online (Sandbox Code Playgroud)

(已-optimize+启用编译)

yield版本实例化一个实现的类IEnumerable和整个shebang:

注意 我省略了实现枚举器块'anonymous'类型的163行CIL代码Program/'<UsingYield>c__Iterator0'.在这里查看: https: //gist.github.com/1384014

.method public static hidebysig 
       default class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> UsingYield ()  cil managed 
{
    .custom instance void class [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::'.ctor'() =  (01 00 00 00 ) // ....

    // Method begins at RVA 0x20f4
// Code size 16 (0x10)
.maxstack 3
.locals init (
    class Program/'<UsingYield>c__Iterator0'    V_0)
IL_0000:  newobj instance void class Program/'<UsingYield>c__Iterator0'::'.ctor'()
IL_0005:  stloc.0 
IL_0006:  ldloc.0 
IL_0007:  dup 
IL_0008:  ldc.i4.s 0xfffffffe
IL_000a:  stfld int32 Program/'<UsingYield>c__Iterator0'::$PC
IL_000f:  ret 
} // end of method Program::UsingYield
Run Code Online (Sandbox Code Playgroud)

阵列版本似乎更简单:

.method public static hidebysig 
       default class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> ReturningArray ()  cil managed 
{
    // Method begins at RVA 0x2110
// Code size 12 (0xc)
.maxstack 8
IL_0000:  ldc.i4.1 
IL_0001:  newarr [mscorlib]System.Int32
IL_0006:  dup 
IL_0007:  ldc.i4.0 
IL_0008:  ldc.i4.s 0x2a
IL_000a:  stelem.i4 
IL_000b:  ret 
} // end of method Program::ReturningArray
Run Code Online (Sandbox Code Playgroud)

实际的运行时性能上,PROFILE PROFILE PROFILE!

  • @ KeesC.Bakker:就生成的代码而言,它是_complex_.您将其用于其他地方提到的原因:(a)延迟执行(b)抽象(您获得状态机功能,代价是程序员没有明显的复杂性).此外,没有人说JIT引擎不会内联相关方法并接近相同的结果.个人资料,个人资料! (3认同)