实例化,如果空变量 [英] Instantiating a variable if null

查看:142
本文介绍了实例化,如果空变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

if (x == null) x = new X();

x = x ?? new X();

这两个实际上是更好的性能?一旦编译做他们有效风一样的东西(会 X = X; 是一个NO-OP结果)?

which of these two is actually more performant? once compiled do they effectively wind up as the same thing (would x = x; be a NO-OP as a result)?

推荐答案

看着中间语言code是有区别的:

Looking at the intermediate language code there is a difference:

.method private hidebysig instance void Method1() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldfld class X Program::x
    L_0006: brtrue.s L_0013
    L_0008: ldarg.0 
    L_0009: newobj instance void X::.ctor()
    L_000e: stfld class X Program::x
    L_0013: ret 
}

.method private hidebysig instance void Method2() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldarg.0 
    L_0002: ldfld class X Program::x
    L_0007: dup 
    L_0008: brtrue.s L_0010
    L_000a: pop 
    L_000b: newobj instance void X::.ctor()
    L_0010: stfld class X Program::x
    L_0015: ret 
}

下面是编译得到这个code我:

Here's the code I compiled to get this:

void Method1()
{
    if (x == null) x = new X();
}

void Method2()
{
    x = x ?? new X();
}

要确保这是更快,你要定时两种。

To be sure which is faster you should time both.


Method     Initial condition   Iterations per second
---------------------------------------------------
NullCheck  x is null           33 million  
Coalesce   x is null           33 million
NullCheck  x is not null       40 million
Coalesce   x is not null       33 million

结论:

  • 它们是关于在这种情况下,其中的值是最初为null相同。
  • 使用if语句是比当X是已经没有空的空合并运算符相当快的方法。

的差异,当x不是空的样子,可能是由于空合并运算符分配x的值回X( stfld 在伊利诺斯州),而空检查跃过 stfld 指令时,x是不为空。

The difference when x is not null looks like it might be due to the null coalescing operator assigning the value of x back to x (stfld in IL), whereas the null check jumps over the stfld instruction when x is not null.

两者都是如此之快,你必须有一个的非常的紧密循环,以发现其中的差别。您应该只,如果你有异形的code与您的数据让这些类型的性能优化。不同的情况,不同版本的.NET中,不同的编译器等可能会产生不同的结果。

Both are so fast that you'd have to have a very tight loop to notice the difference. You should only make these sorts of performance optimizations if you have profiled your code with your data. Different situations, different versions of .NET, different compilers, etc. may produce different results.

在万一有人想知道我是如何得到这些结果或复制他们,这里的code我用:

In case someone wants to know how I got these results or reproduce them, here's the code I used:

using System;

class X { }

class Program
{
    private X x;

    private X xNull = null;
    private X xNotNull = new X();

    private void Method1Null()
    {
        x = xNull;
        if (x == null) x = xNotNull;
    }

    private void Method2Null()
    {
        x = xNull;
        x = x ?? xNotNull;
    }

    private void Method1NotNull()
    {
        x = xNotNull;
        if (x == null) x = xNotNull;
    }

    private void Method2NotNull()
    {
        x = xNotNull;
        x = x ?? xNotNull;
    }

    private const int repetitions = 1000000000;

    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(() => { Method1Null(); });
        Time(() => { Method2Null(); });
        Time(() => { Method1NotNull(); });
        Time(() => { Method2NotNull(); });
        Console.WriteLine("Finished");
        Console.ReadLine();
    }

    private static void Main()
    {
        new Program().Run();
    }
}

免责声明:无基准是完美的,这bechmark是的的完善,主要是为了让事情变得简单。我如运行各种不同的测试与以不同的顺序的方法中,有和没有热身第一,随着不同的时间长度,等等。我得到大致每次相同的结果。我没有什么需要证明的一种方式或其他使任何偏见偏袒一种方法或另一种是偶然的。

Disclaimer: No benchmark is perfect, and this bechmark is far from perfect, mainly to keep things simple. I've run numerous different tests e.g. with the methods in a different order, with and without "warming up" first, over different lengths of time, etc. I get roughly the same results each time. I didn't have anything to prove one way or the other so any bias favoring one method or the other is accidental.

这篇关于实例化,如果空变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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