Phi*_*oie 35 c# setter performance properties object-initialization
这是一个简单的问题:这之间是否存在任何(性能)差异:
Person person = new Person()
{
Name = "Philippe",
Mail = "phil@phil.com",
};
Run Code Online (Sandbox Code Playgroud)
还有这个
Person person = new Person();
person.Name = "Philippe";
person.Mail = "phil@phil.com";
Run Code Online (Sandbox Code Playgroud)
您可以想象具有更多属性的更大对象.
Mar*_*ers 43
它们几乎完全等效,只是第一种方法(使用对象初始化程序)仅适用于C#3.0及更高版本.任何表现差异都很小,不值得担心.
它们产生几乎相同的IL代码.第一个给出了这个:
.method private hidebysig instance void ObjectInitializer() cil managed
{
.maxstack 2
.locals init (
[0] class Person person,
[1] class Person <>g__initLocal0)
L_0000: newobj instance void Person::.ctor()
L_0005: stloc.1
L_0006: ldloc.1
L_0007: ldstr "Philippe"
L_000c: callvirt instance void Person::set_Name(string)
L_0011: ldloc.1
L_0012: ldstr "phil@phil.com"
L_0017: callvirt instance void Person::set_Mail(string)
L_001c: ldloc.1
L_001d: stloc.0
L_001e: ldloc.0
L_001f: callvirt instance string [mscorlib]System.Object::ToString()
L_0024: pop
L_0025: ret
}
Run Code Online (Sandbox Code Playgroud)
第二个给出了这个:
.method private hidebysig instance void SetProperties() cil managed
{
.maxstack 2
.locals init (
[0] class Person person)
L_0000: newobj instance void Person::.ctor()
L_0005: stloc.0
L_0006: ldloc.0
L_0007: ldstr "Philippe"
L_000c: callvirt instance void Person::set_Name(string)
L_0011: ldloc.0
L_0012: ldstr "phil@phil.com"
L_0017: callvirt instance void Person::set_Mail(string)
L_001c: ldloc.0
L_001d: callvirt instance string [mscorlib]System.Object::ToString()
L_0022: pop
L_0023: ret
}
Run Code Online (Sandbox Code Playgroud)
如您所见,生成了几乎相同的代码.请参阅下面的我编译的确切C#代码.
性能测量显示非常相似的结果,使用对象初始化程序语法的性能提升非常小:
Method Iterations per second ObjectInitializer 8.8 million SetProperties 8.6 million
我用来测试性能的代码:
using System;
class Person
{
public string Name { get; set; }
public string Mail { get; set; }
}
class Program
{
private void ObjectInitializer()
{
Person person = new Person()
{
Name = "Philippe",
Mail = "phil@phil.com",
};
person.ToString();
}
private void SetProperties()
{
Person person = new Person();
person.Name = "Philippe";
person.Mail = "phil@phil.com";
person.ToString();
}
private const int repetitions = 100000000;
private void Time(Action action)
{
DateTime start = DateTime.UtcNow;
for (int i = 0; i < repetitions; ++i)
{
action();
}
DateTime end = DateTime.UtcNow;
Console.WriteLine(repetitions / (end - start).TotalSeconds);
}
private void Run()
{
Time(ObjectInitializer);
Time(SetProperties);
Console.WriteLine("Finished");
Console.ReadLine();
}
private static void Main()
{
new Program().Run();
}
}
Run Code Online (Sandbox Code Playgroud)
值得注意的另一件事是:
如果您在构造函数中未能处理异常,则会收到TypeInitializationException.虽然这看起来可能并不那么糟糕,但事实是它隐藏了问题的真正原因,并且使得追踪变得更加困难.
另一方面,如果使用对象初始值设定项,则在构造函数之外单独调用每个属性,并且任何抛出的异常都将非常明确且非常明显:它们不会被TypeInitializationException屏蔽.
通常,在构造函数中抛出异常是个坏主意.如果您想避免这种情况,请使用初始化程序.
归档时间: |
|
查看次数: |
11857 次 |
最近记录: |