首頁  >  文章  >  後端開發  >  為什麼 Lambda 比 C 中的普通函數更可優化?

為什麼 Lambda 比 C 中的普通函數更可優化?

Susan Sarandon
Susan Sarandon原創
2024-11-24 06:00:19612瀏覽

Why are Lambdas More Optimizable than Plain Functions in C  ?

與普通函數相比,為什麼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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn