2016-05-27 67 views
9

我有一個頂級lambda函數,然後在這個lambda內部有幾個嵌套lambda函數。嵌套Lambda函數 - 性能影響

將lambda嵌入其他lambda中是一個好主意嗎?是否有任何性能影響?

例如,

auto Multiplier1 = []() -> int 
{ 
    auto Multiplier2 = [](int i) -> int 
    { 
     auto Multiplier3 = [](int i) -> int 
     { 
      return i * 2; 
     }; 
     std::cout << "Calling another lambda 2\n"; 
     return Multiplier3(i * 100); 
    }; 

    int i = 10; 
    std::cout << "Calling another lambda 1\n"; 
    int ret = Multiplier2(i); 
    return ret; 
}; 

int ret = Multiplier1(); 
std::cout << ret << "\n"; 

在上面的例子中,我可以將Multiplier2和Multiplier3重新分解爲單獨的函數。與此相比,這是更好的方法嗎?

我正在修改已經在生產中的代碼,因此,我是在一個兩難的問題,是否將它重新分解爲單獨的函數或管理使用lambda函數。

+3

「*是否有任何性能影響?*」對於無捕食lambdas,因爲你有,絕對不是。 – ildjarn

+1

誠實的問題:爲什麼不圍繞你有時間的罐頭示例進行循環。那麼重構和時間呢?正如@ildjarn所指出的那樣,您需要確保這些lambda的簽名與您生產中的真正lambda相同。 – Hal

+0

@Hal你說得對。最好的事情是時間和檢查性能。 –

回答

12

詢問編碼風格表達的結果對性能的影響總是錯誤的問題。

編譯器在優化時認爲表達意圖,而不是代碼的佈局。

這個例子是極端的,但值得向您展示gcc編譯器編譯選項-O2的代碼。

重構上述代碼除去,將通過使用cout產生噪聲:

auto Multiplier1 = []() -> int 
{ 
    auto Multiplier2 = [](int i) -> int 
    { 
     auto Multiplier3 = [](int i) -> int 
     { 
      return i * 2; 
     }; 
     return Multiplier3(i * 100); 
    }; 

    int i = 10; 
    int ret = Multiplier2(i); 
    return ret; 
}; 

extern void emit(int); 

int main() 
{ 
    int ret = Multiplier1(); 
    emit(ret); 
} 

gcc -S -O2 -std=c++14收率編譯:

main: 
     subq $8, %rsp 
     movl $2000, %edi 
     call emit(int) 
     xorl %eax, %eax 
     addq $8, %rsp 
     ret 

注意,優化器已經穿過看到所有的代碼,並意識到此代碼可能採取的唯一行動(重要)是調用參數值爲2000的函數emit

這個教訓總是應該表達的意圖優雅(即以易於理解和維護的方式),並允許編譯器完成其工作,以最少的時間和/或代碼大小發送實現該意圖的代碼。