加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – .NET对象创建,速度更快?

发布时间:2020-12-15 20:49:56 所属栏目:百科 来源:网络整理
导读:这两种对象创建方式之间有区别吗? new MyClass() { Id = 1,Code = "Test" }; 要么 MyClass c = new MyClass();c.Id = 1;c.Code = "Test"; 什么更快?我假设2之间没有区别. 解决方法 第二个可能几乎肯定会更快,因为从逻辑上讲,涉及的任务较少.在第一种情况下
这两种对象创建方式之间有区别吗?

new MyClass() { Id = 1,Code = "Test" };

要么

MyClass c = new MyClass();
c.Id = 1;
c.Code = "Test";

什么更快?我假设2之间没有区别.

解决方法

第二个可能几乎肯定会更快,因为从逻辑上讲,涉及的任务较少.在第一种情况下,代码实际上等同于:

MyClass tmp = new MyClass()
tmp.Id = 1;
tmp.Code = "Test";
MyClass c = tmp;

当您声明一个新变量时,JIT编译器很可能会忽略它们 – 如果您使用对象初始化程序分配给现有变量,它将无法执行此操作.

编辑:我刚刚尝试使用和不使用优化进行编译,在这个“新变量”的情况下,如果它正在优化,C#编译器会忽略这两个.否则它没有(但JIT仍然可以).在“重新分配”的情况下,它可以产生可观察到的差异,因此我不希望进行相同的优化.我没有检查过.

我会非常惊讶地看到它实际上产生了显着差异的情况,所以我选择了更具可读性的选项,IMO是第一个.

编辑:我认为人们可能对基准测试感兴趣,表明它有所作为.这是一个故意可怕的代码,使隐藏的额外任务变慢 – 我已经创建了一个大的,可变的结构. Urgh.无论如何…

using System;
using System.Diagnostics;

struct BigStruct
{
    public int value;
    #pragma warning disable 0169
    decimal a1,a2,a3,a4,a5,a6,a7,a8;
    decimal b1,b2,b3,b4,b5,b6,b7,b8;
    decimal c1,c2,c3,c4,c5,c6,c7,c8;
    decimal d1,d2,d3,d4,d5,d6,d7,d8;
    #pragma warning restore 0169
}

class Test
{
    const int Iterations = 10000000;

    static void Main()
    {
        Time(NewVariableObjectInitializer);
        Time(ExistingVariableObjectInitializer);
        Time(NewVariableDirectSetting);
        Time(ExistingVariableDirectSetting);
    }

    static void Time(Func<int> action)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        Console.WriteLine("{0}: {1}ms",action.Method.Name,stopwatch.ElapsedMilliseconds);
    }

    static int NewVariableObjectInitializer()
    {
        int total = 0;
        for (int i = 0; i < Iterations; i++)
        {
            BigStruct b = new BigStruct { value = i };
            total += b.value;
        }
        return total;
    }

    static int ExistingVariableObjectInitializer()
    {
        int total = 0;
        BigStruct b;
        for (int i = 0; i < Iterations; i++)
        {
            b = new BigStruct { value = i };
            total += b.value;
        }
        return total;
    }

    static int NewVariableDirectSetting()
    {
        int total = 0;
        for (int i = 0; i < Iterations; i++)
        {
            BigStruct b = new BigStruct();
            b.value = i;
            total += b.value;
        }
        return total;
    }

    static int ExistingVariableDirectSetting()
    {
        int total = 0;
        BigStruct b;
        for (int i = 0; i < Iterations; i++)
        {
            b = new BigStruct();
            b.value = i;
            total += b.value;
        }
        return total;
    }
}

结果(使用/ o / debug-):

NewVariableObjectInitializer: 3328ms
ExistingVariableObjectInitializer: 3300ms
NewVariableDirectSetting: 1464ms
ExistingVariableDirectSetting: 1491ms

我有些惊讶于NewVariableObjectInitializer版本比直接设置版本慢……看起来C#编译器没有像它对引用类型那样优化这种情况.我怀疑在价值类型方面有一些微妙的东西会阻止它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读