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 why ?
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 why ?
IMO the speed should be exactly the same for both versions. Maybe your benchmark is flawed?
It seems that in this case you can make DoStuff a static method.
So rather then use
Stuff.DoStuff();
Have a look at
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).
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.
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.