开发者

is var x = new Stuff(); x.DoStuff(); faster than new Stuff().DoStuff();?

is var x = new Stuff(); x.DoStuff();faster than new Stuff().DoStuff(); ?

I'm not sure why but I noticed in my code that the first method makes it faster, anybody knows which one is faster and开发者_Python百科 why ?


Actually the second should be faster as it performs fewer operations. Let's take this program for example:

class Program
{
    public void Foo() { }

    static void Main() 
    {}

    static void Method1()
    {
        var x = new Program();
        x.Foo();
    }

    static void Method2()
    {
        new Program().Foo();
    }
}

Here's how Method1 and Method2 look like when compiled in Release mode:

.method private hidebysig static void Method1() cil managed
{
    .maxstack 1
    .locals init (
        [0] class Program x)
    L_0000: newobj instance void Program::.ctor()
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: callvirt instance void Program::Foo()
    L_000c: ret 
}

.method private hidebysig static void Method2() cil managed
{
    .maxstack 8
    L_0000: newobj instance void Program::.ctor()
    L_0005: call instance void Program::Foo()
    L_000a: ret 
}

Of course this sort of micro-optimization questions should never be asked.


It seems that in this case you can make DoStuff a static method.

So rather then use

Stuff.DoStuff();

Have a look at

  • Static Classes and Static Class Members (C# Programming Guide)
  • C# method can be made static, but should it?


This is the IL code that they produce:

new Stuff().DoStuff();:

  // Code size       11 (0xb)
  .maxstack  8
  IL_0000:  newobj     instance void ConsoleApplication1.Stuff::.ctor()
  IL_0005:  call       instance void ConsoleApplication1.Stuff::DoStuff()
  IL_000a:  ret

var x = new Stuff(); x.DoStuff();:

  // Code size       13 (0xd)
  .maxstack  1
  .locals init ([0] class ConsoleApplication1.Stuff x)
  IL_0000:  newobj     instance void ConsoleApplication1.Stuff::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  callvirt   instance void ConsoleApplication1.Stuff::DoStuff()
  IL_000c:  ret

When iterating over the two variations 1000000 times, the new Stuff().DoStuff(); version uses around 20% less time. Nothing I would bother about (the difference was 0.8 ms on one million iterations).


IMO the speed should be exactly the same for both versions. Maybe your benchmark is flawed?


The first version needs to store the reference to x in the locals, which the latter version doesn't, this cannot be done without consuming additional instructions. However, even the slightest change in the code will change the performance.

And please do not over-estimate the efficiency of the JIT'er, the JIT needs to balance speed of compilation with the efficiency of the code generated, the JIT'er is not the pen-ultimate application for generating machine code from CIL code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜