與普通函數相比,為什麼Lambda 允許增強編譯器最佳化
Nicolai Josuttis 的C 標準函式庫(第二版)斷言lambda可以與普通函數相比,編譯器可以更有效地最佳化。這項優勢源自於 lambda 作為函數物件的本質。
當將 lambda 傳遞給函數模板時,它會被實例化為專門針對該物件定制的新函數。這使得編譯器可以毫不費力地內聯 lambda 呼叫。相反,對於普通函數,函數指標將傳遞給函數模板。傳統上,編譯器在透過函數指標進行內聯呼叫時遇到困難。
為了說明這個概念,請考慮以下函數模板:
template <typename Iter, typename F> void map(Iter begin, Iter end, F f) { for (; begin != end; ++begin) *begin = f(*begin); }
使用lambda 呼叫此函數:
int a[] = { 1, 2, 3, 4 }; map(begin(a), end(a), [](int n) { return n * 2; });
導致以下內容創建的實例化器:
template <> void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) { for (; begin != end; ++begin) *begin = f.operator()(*begin); }
在這種情況下,編譯器可以訪問_some_lambda_type::operator() 並且可以無縫地內聯呼叫它。每個 lambda 都有不同的類型,因此在 map() 中使用不同的 lambda 將產生新的實例化。
但是,如果使用函數指針:
map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) { for (; begin != end; ++begin) *begin = f(*begin); }
編譯器將無法內聯對f 的調用,直到對map() 的包含調用也被內聯,從而允許它精確定位特定函數。這凸顯了 lambda 在編譯器最佳化方面相對於普通函數的優勢。
以上是為什麼 Lambda 比 C 中的普通函數更可優化?的詳細內容。更多資訊請關注PHP中文網其他相關文章!