c#3.0中的对象初始化程序是否比常规方法更快?
这是否更快
Object object = new Object
{
id = 1;
}
比这个?
Object object = new Object()
object.id = 1;
答案 0 :(得分:22)
在发布模式下,他们将编译为完全相同的IL代码(假设您实际使用的是具有id
属性的类型而不是Object
)< / p>
因此,根据定义,没有性能差异。
我不知道哪一个编译速度会更快,但编译时间差别很小,你可能不在乎。
但是,对象初始化程序语法写得更快(输入更少),因此您应该使用它。
答案 1 :(得分:9)
好的,根据[SLaks] [2]的评论,并在阅读后自我测试,结果证明我在这里描述的差异只出现在调试模式中。如果您为发布版编译,它们都会编译为相同的代码。每天都学到新东西:)
(所以其余的答案都假定为调试模式。)
p>
不同之处在于使用对象初始值设定项,如下所示:
Object object = new Object
{
id = 1;
}
代码实际上是编译好像你写的那样:
Object temp = new Object();
temp.id = 1;
Object object = temp;
(当然,除非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;
}
}
}
并编译它,通过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
}
如果查看代码,M2和M3之间唯一不同的是第二个本地的名称(<>g__initLocal0
vs temp
)。
但正如其他人已经回答的那样,差异不会使你应该注意到任何性能差异。
答案 2 :(得分:2)
AFAIK它只是语法糖 - 产生的IL将是相同的
答案 3 :(得分:1)
不,这是一回事。
答案 4 :(得分:1)
键入可能会更快,但它会编译为相同的代码,因此没有运行时的好处。
答案 5 :(得分:1)
如果存在任何性能差异(我怀疑有任何差异),它们可以忽略不计。仅在分析器告知您这样做时进行优化。
答案 6 :(得分:1)
我没有对它进行基准测试,但是如果他们没有编译到相同的东西我就会被贬低。
那就是说,当我需要像
这样的东西时,我更容易打字var bob = service.GetSingle( new Constraint { UserName = "Bob" } );
我非常不喜欢重复分配属性,如
var c = new Constraint();
c.UserName = "Bob";
c.Position = Positions.Manager;
var bob = service.GetSingle( c );