2009-12-15 64 views
0

var x = new Stuff(); x.DoStuff();快于new Stuff().DoStuff();是var x = new Stuff(); x.DoStuff();比新东西()更快。DoStuff();?

我不知道为什么,但我注意到在我的代码中,第一种方法使其更快,任何人都知道哪一个更快,为什么?

+3

我很确定它在编译器中做同样的事情。你是否比较过IL? – 2009-12-15 08:21:23

+1

你是怎么测量的?我认为测量这样一小段代码是相当困难的。您最好优化DoStuff方法,并且只有在它确实是瓶颈时。 – jmservera 2009-12-15 08:30:45

+1

从这样一个简单的代码示例中,我没有看到如何声明事情,我没有看到如何设计任何合理的基准。顺便说一下,我没有投票表决。请考虑让问题更详细一些,代码示例更加明确。 – BillW 2009-12-15 08:36:11

回答

9

其实第二个应该更快,因为它执行更少的操作。让我们这个节目,例如:

class Program 
{ 
    public void Foo() { } 

    static void Main() 
    {} 

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

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

这里的方法1和方法2怎么看时,在Release模式下进行编译,如:

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

当然这种微优化问题,不应该问。

+5

此外,JIT编译器可能会创建相同的机器代码。 – 2009-12-15 08:32:41

+2

+1:“当然这种微观优化问题绝不应该被问到。” -1的问题。 – Andrew 2009-12-15 08:45:06

+1

这是所有优化启用?我已经看到编译器偶尔删除变量,使它们相同... – 2009-12-15 12:12:14

3

IMO的两个版本的速度应该完全一样。也许你的基准是有缺陷的?

4

这是他们生产的IL代码:

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 

当在两个变型迭代百万次,new Stuff().DoStuff();版本使用少约20%的时间。没有什么我会困扰的(差异是在一百万次迭代中为0.8毫秒)。

+4

是的,我认为如果这种微乎其微的差异对我很重要,我不会首先使用.NET。 – dan 2009-12-15 08:41:51

1

第一个版本需要将对x的引用存储在当地人中,后者版本没有,这不能在不消耗附加指令的情况下完成。但是,即使代码稍有变化也会改变性能。

请不要高估JIT'er的效率,JIT需要平衡编译速度和生成代码的效率,JIT'er不是生成机器码的终极应用程序来自CIL代码。