2009-12-15 60 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代碼。