是否通过对象初始化设置属性:有什么区别? [英] Setting properties via object initialization or not : Any difference ?

查看:29
本文介绍了是否通过对象初始化设置属性:有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简单的问题:这之间有什么(性能)差异:

Person person = new Person(){Name = "菲利普",邮件 = "phil@phil.com",};

还有这个

Person person = new Person();person.Name = "菲利普";person.Mail = "phil@phil.com";

您可以想象具有更多属性的更大对象.

解决方案

除了第一种方法(使用 object initializer) 仅适用于 C# 3.0 及更新版本.任何性能差异都只是微小的,不值得担心.

它们生成几乎相同的 IL 代码.第一个给出了这个:

.method private hidebysig instance void ObjectInitializer() cil managed{.maxstack 2.locals 初始化([0] 类人人,[1] 类人 <>g__initLocal0)L_0000: newobj 实例 void Person::.ctor()L_0005:stloc.1L_0006: ldloc.1L_0007: ldstr "菲利普"L_000c: callvirt 实例 void Person::set_Name(string)L_0011: ldloc.1L_0012: ldstr "phil@phil.com"L_0017: callvirt 实例 void Person::set_Mail(string)L_001c:ldloc.1L_001d:stloc.0L_001e:ldloc.0L_001f:callvirt 实例字符串 [mscorlib]System.Object::ToString()L_0024:流行L_0025:返回}

第二个给出了这个:

.method private hidebysig 实例 void SetProperties() cil 管理{.maxstack 2.locals 初始化([0] 类人人)L_0000: newobj 实例 void Person::.ctor()L_0005:stloc.0L_0006: ldloc.0L_0007: ldstr "菲利普"L_000c: callvirt 实例 void Person::set_Name(string)L_0011: ldloc.0L_0012: ldstr "phil@phil.com"L_0017: callvirt 实例 void Person::set_Mail(string)L_001c:ldloc.0L_001d:callvirt 实例字符串 [mscorlib]System.Object::ToString()L_0022:流行L_0023:返回}

如您所见,生成的代码几乎相同.有关我编译的确切 C# 代码,请参见下文.

性能测量显示非常相似的结果,但使用对象初始值设定项语法的性能提升非常小:

<前>每秒方法迭代次数ObjectInitializer 880 万SetProperties 860 万

我用来测试性能的代码:

使用系统;班级人物{公共字符串名称 { 获取;放;}公共字符串邮件 { 获取;放;}}课程计划{私有无效 ObjectInitializer(){人人 = 新人(){Name = "菲利普",邮件 = "phil@phil.com",};person.ToString();}私有无效 SetProperties(){人人 = 新人();person.Name = "菲利普";person.Mail = "phil@phil.com";person.ToString();}private const int 重复次数 = 100000000;私人无效时间(行动行动){日期时间开始 = DateTime.UtcNow;for (int i = 0; i <重复次数; ++i){行动();}日期时间结束 = DateTime.UtcNow;Console.WriteLine(repetitions/(end - start).TotalSeconds);}私有无效运行(){时间(对象初始化器);时间(设置属性);Console.WriteLine("完成");Console.ReadLine();}私有静态无效 Main(){新程序().运行();}}

Here's a simple question : Is there any (performance) difference between this :

Person person = new Person()
{
  Name = "Philippe",
  Mail = "phil@phil.com",
};

and this

Person person = new Person();
person.Name = "Philippe";
person.Mail = "phil@phil.com";

You can imagine bigger object with more properties.

解决方案

They are almost exactly equivalent except that the first method (using an object initializer) only works in C# 3.0 and newer. Any performance difference is only minor and not worth worrying about.

They produce almost identical IL code. The first gives this:

.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 
}

The second gives this:

.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 
}

As you can see, nearly identical code is generated. See below for the exact C# code I compiled.

Performance measurements show very similar results with a very small performance improvement for using the object initializer syntax:

Method               Iterations per second
ObjectInitializer    8.8 million
SetProperties        8.6 million

Code I used for testing the performance:

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();
    }
}

这篇关于是否通过对象初始化设置属性:有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆