对象初始化程序性能

use*_*348 16 .net c#-3.0

c#3.0中的对象初始值设定项比常规方式更快吗?

这更快吗?

Object object = new Object
{
    id = 1;
}
Run Code Online (Sandbox Code Playgroud)

比这个 ?

Object object = new Object()

object.id = 1;
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 23

在发布模式下,它们将编译为完全相同的 IL代码(假设您实际上使用的是具有id属性的类型而不是Object)

因此,根据定义,将没有性能差异.

我不知道哪一个编译速度会更快,但编译时间差别很小,你可能不在乎.

但是,对象初始化程序语法写得更快(更少打字),因此您应该使用它.


ang*_*son 9

好的,根据[SLaks] [2]的评论,并在阅读后测试自己,结果证明我在这里描述的差异只出现在调试模式中.如果您为发布版编译,它们都会编译为相同的代码.每天学些新东西 :)


(所以其余的答案都假定为调试模式.)

还有就是在IL的差异产生的,相反的是其他人在这里已经回答了,但不同的是可以忽略不计,而不是实际上应该对你的程序的任何性能影响的.

区别在于使用对象初始值设定项,如下所示:

Object object = new Object
{
    id = 1;
}
Run Code Online (Sandbox Code Playgroud)

代码实际上是编译好像你写的那样:

Object temp = new Object();
temp.id = 1;
Object object = temp;
Run Code Online (Sandbox Code Playgroud)

(当然,除非Object没有Id字段/属性,否则在不使用逐字标识符语法"@object"的情况下实际上无法命名变量"object".)

这为什么重要?好吧,您可能注意到的一个区别是,如果任何赋值抛出异常(将值写入对象,或者从表达式或函数中获取值抛出异常),那么使用对象初始值设定项,您就赢了实际上看到变量中的任何对象,而在"手动"代码中,对象将在那里,初始化直到发生异常的点.

一个微小的差异,不应该有很大的性能差异,但可能会改变您的程序的行为.

这可以通过查看IL来验证.拿这个C#程序:

using System;

namespace ConsoleApplication3
{
    class Test
    {
        public Int32 Id { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            M1();
            M2();
        }

        static void M1()
        {
            Test t = new Test();
            t.Id = 1;
        }

        static void M2()
        {
            Test t = new Test { Id = 1 };
        }

        static void M3()
        {
            Test t;
            Test temp = new Test();
            temp.Id = 1;
            t = temp;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并编译它,通过Reflector运行它,你将获得M1,M2和M3:

.method private hidebysig static void M1() cil managed
{
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication3.Test t)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: ldc.i4.1 
    L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
    L_000e: nop 
    L_000f: ret 
}

.method private hidebysig static void M2() cil managed
{
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication3.Test t,
        [1] class ConsoleApplication3.Test <>g__initLocal0)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
    L_0006: stloc.1 
    L_0007: ldloc.1 
    L_0008: ldc.i4.1 
    L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
    L_000e: nop 
    L_000f: ldloc.1 
    L_0010: stloc.0 
    L_0011: ret 
}

 .method private hidebysig static void M3() cil managed
{
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication3.Test t,
        [1] class ConsoleApplication3.Test temp)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication3.Test::.ctor()
    L_0006: stloc.1 
    L_0007: ldloc.1 
    L_0008: ldc.i4.1 
    L_0009: callvirt instance void ConsoleApplication3.Test::set_Id(int32)
    L_000e: nop 
    L_000f: ldloc.1 
    L_0010: stloc.0 
    L_0011: ret 
}
Run Code Online (Sandbox Code Playgroud)

如果查看代码,M2和M3之间唯一不同的是第二个本地(<>g__initLocal0vs temp)的名称.

但正如其他人已经回答的那样,差异不会使你应该注意到任何性能差异.