2012-09-28 29 views
3

考慮以下情況是否爲變量添加開銷創建本地別名?

void func(const A& a) 
{ 
    //Case 1: 
    const int& val = a->b->c->d; 
    func1(val); 
    func2(val); 

    //Case 2: 
    func1(a->b->c->d); 
    func2(a->b->c->d); 

    //Case3: 
    int val = a->b->c->d; 
    func1(val); 
    func2(val); 
} 

w.r.t可讀性,CASE3是最直接的

w.r.t速度,一個體面的編譯器,是上述情況等同呢?如果不是最快和最慢的哪一個?

假設所有指針都是原始指針,並且它們指向堆中的對象。

更新:假設參數是const,如上所示,因此func1和func2可以通過值或通過const引用接受參數。

+3

值得注意的是,如果'func1'可以修改'a','a-> b','a-> b-> c'和/或''a'',那麼這三個代碼片段實際上可能是非等價的。 A-> B-> C-> D'。因此,編譯器可以將它們全部優化爲相同代碼的唯一方法是,它是否可以訪問'func1'的定義,或者可以以某種方式確認它們在功能上等同。 – ruakh

+0

@ruakh如果func1只傳遞了'd'的值,那麼'func1'如何修改'a','b'或'c'? –

+0

@Dave:也許'a'是一個全局變量。 –

回答

1

假設兩種功能採取它們的參數由值,情況3是至少一樣快,情況1,其至少一樣快病例2

作爲評價提到ruakh,有一些複雜的數據流在優化發生之前需要分析。

如果函數參數是引用,那麼值的最終內存負載可能永遠不會發生。然後案例1將是最快的。

如果這些是宏而不是函數,所有投注都關閉。

0

在第一種情況下,您在val中對a-> b-> c-> d進行引用,因此編譯器的pov val是一個取消引用的指針。

第三個速度是最快的,因爲它只是創建一個值的副本而不是使用該值。

與前兩種方法的問題是,你必須取消引用,所以你要做的

case 1 
lea eax,[ebp+a] 
push eax 

case 2 
lea eax, [ebp+a] 
lea ebx, [eax] 
.... 

case 3 
mov eax [ebp+val] 
push eax 

指針來獲取值,你可以清楚地看到,第三個是最快的

+0

我明白了。但是如果d不是原始的,那麼case1或case2是最快的嗎? – balki

+0

情況1會比情況2更快 –