【问题标题】:Optimizing the property getter for a ValueType优化 ValueType 的属性 getter
【发布时间】:2024-05-02 19:35:02
【问题描述】:

我有这样的类的层次结构

public class Class1
{
    internal DateTime time = DateTime.Now;
}

public class Class2
{
    internal Class1 C1;

    public Class2(Class1 c1) { C1 = c1; }

    public DateTime Time { get { return C1.time; } }
}

public class Class3
{
    internal Class2 C2;

    public Class3(Class2 c2) { C2 = c2; }

    public DateTime Time { get { return C2.Time; } }
}

public class Class4
{
    internal Class3 C3;

    public Class4(Class3 c3) { C3 = c3; }

    public DateTime Time { get { return C3.Time; } }
}

我想知道我什么时候打电话

Class4 C4 = new Class4(.....);  
Console.WriteLine(C4.Time);

是否会将 ValueType 数据(在这种情况下为 DateTime)复制 4 次,或者 JIT 编译器是否会优化代码并将其重新生成为内联版本,例如 C4.C3.C2.C1.time;

C# 编译器不做任何优化。 ILDASM 生成的代码在这里:

// get { return C3.Time; }
.method public hidebysig specialname instance valuetype [mscorlib]System.DateTime 
        get_Time() cil managed
{
  // Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class CSTester.Class3 CSTester.Class4::C3
  IL_0006:  callvirt   instance valuetype [mscorlib]System.DateTime CSTester.Class3::get_Time()
  IL_000b:  ret
} // end of method Class4::get_Time

// get { return C2.Time; }
.method public hidebysig specialname instance valuetype [mscorlib]System.DateTime 
        get_Time() cil managed
{
  // Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class CSTester.Class2 CSTester.Class3::C2
  IL_0006:  callvirt   instance valuetype [mscorlib]System.DateTime CSTester.Class2::get_Time()
  IL_000b:  ret
} // end of method Class3::get_Time

编辑:代码在发布模式下编译并启用优化。

【问题讨论】:

  • 在发布时编译并启用优化?如果是这样,我想 JIT 会完成这项工作。

标签: c# .net optimization compiler-construction inline


【解决方案1】:

也许会。也许不会。也许它会在某些版本的 CLR 上,在某些 CPU 架构上,但不是在其他版本上。

你必须问自己的问题是它到底有多重要。

您有性能目标和基准吗?

你的代码符合他们吗?

如果不是,你有理由相信这是瓶颈吗?

我发现,除了少数应用之外,优化与否之间的差异不太可能有显着差异。

【讨论】:

  • 我想,与实例化引用类型时执行的其他活动相比,复制和分配几个DateTimes 肯定是微不足道的。
  • @Jodrell:我希望如此,是的。我不知道DateTime 有多大,但我怀疑它是否超过 16 个字节...
  • 我的问题与性能无关。显然,未优化的代码可能会多复制几个字节。我什至可以自己做内联。我只是想知道。
  • @sad_man:当您询问优化时,它与性能有何不同?您认为优化除了性能的目的是什么?
【解决方案2】:

Eric Lippert says I don't know 比我更有说服力。

顺便说一句,

int sizeInBytes;
unsafe
{
    sizeInBytes = sizeof(DateTime);
}

对我来说结果为 8,但依赖它会不安全。 24 字节的复制不值得担心。如果是,那么这部分代码可能应该使用较低代的语言。

【讨论】: