c#对象初始化之间的性能差异

c#对象初始化之间的性能差异,c#,C#,这可能是重复的,但我无法从提问时提出的建议中找到与我的问题完全匹配的答案: 在c#中,以下各项之间是否存在很大的性能差异(如果有): vs 不,没有区别,因为它产生相同的IL。 汇编以下文件: class Program { static void Main(string[] args) { var objectA = new Test(); objectA.PropA = 1; objectA.PropB = 10;

这可能是重复的,但我无法从提问时提出的建议中找到与我的问题完全匹配的答案:

在c#中,以下各项之间是否存在很大的性能差异(如果有):

vs


不,没有区别,因为它产生相同的IL。

汇编以下文件:

class Program
{
    static void Main(string[] args)
    {
        var objectA = new Test();
        objectA.PropA = 1;
        objectA.PropB = 10;

        var objectB = new Test() { PropA = 2, PropB = 20 };
    }
}

public class Test
{
    public int PropA { get; set; }
    public int PropB { get; set; }
}
将产生以下IL(释放模式):


在创建实例后,这两种方法都以相同的方式调用setter方法。

最好的方法是测试它。我的直觉告诉我,根据编译器,它会编译成同一个IL。是的,但我不确定我现在是如何工作的,有一个期限即将到来。days@itsme86-正确的方法是查看IL。。。但事实上,后者只是前者的语法糖衣。如果您正朝着一个截止日期努力,这应该不必担心,除非您确实存在性能问题,并且将其缩小到对象初始值设定项(后者几乎不可能).这不完全相同--对象初始值设定项有一个额外的
dup
。然而,更重要的是,您根本没有使用变量,因此对象初始值设定项声明一个额外变量的事实(因为该变量保证永远不会有仅部分初始化的值)被优化掉了。我建议您在初始化每个实例后添加一个
控制台。WriteLine(objectA)
(或
objectB
),您将看到对象初始值设定项代码明显不同。不是说你应该关心这里的性能,而是有区别。@KirkWoll:是的,我完全删除了。我还用access检查了它,然后所有的
dup
都消失了,但是对象初始值设定项有一个额外的
stloc
ldloc
(请参见),但我不知道它们到底是什么,因为我不“精通IL”。你应该比较抖动生成的实际机器语言,而不是IL。基本上,
stloc
ldloc
是用来存储和加载局部变量的。(尽管这过于简化了,因为它们通常用于代码中未声明的变量)例如:对象初始化器语法在一个存储位置创建对象,对其进行初始化,最后将其存储在表示声明的变量的最终位置。这可能会产生微妙的语义影响,因为这意味着变量在完全初始化之前无法使用(可能在不同的线程上)。
var object = new object { propx = x, propy = y};
class Program
{
    static void Main(string[] args)
    {
        var objectA = new Test();
        objectA.PropA = 1;
        objectA.PropB = 10;

        var objectB = new Test() { PropA = 2, PropB = 20 };
    }
}

public class Test
{
    public int PropA { get; set; }
    public int PropB { get; set; }
}
IL_0000: newobj instance void InitTest.Test::.ctor()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: callvirt instance void InitTest.Test::set_PropA(int32)
IL_000c: ldc.i4.s 10
IL_000e: callvirt instance void InitTest.Test::set_PropB(int32)
IL_0013: newobj instance void InitTest.Test::.ctor()
IL_0018: dup
IL_0019: ldc.i4.2
IL_001a: callvirt instance void InitTest.Test::set_PropA(int32)
IL_001f: dup
IL_0020: ldc.i4.s 20
IL_0022: callvirt instance void InitTest.Test::set_PropB(int32)
IL_0027: pop
IL_0028: ret