」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 為什麼 Lambda 比 C++ 中的普通函數更可優化?

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

發佈於2024-11-16
瀏覽:308

Why are Lambdas More Optimizable than Plain Functions in C  ?

與普通函數相比,為什麼Lambda 允許增強編譯器優化

Nicolai Josuttis 的C 標準庫(第二版)斷言lambda可以與普通函數相比,編譯器可以更有效地最佳化。這項優勢源自於 lambda 作為函數物件的本質。

當 lambda 傳遞給函數模板時,它會被實例化為專門針對該物件定制的新函數。這使得編譯器可以毫不費力地內聯 lambda 呼叫。相反,對於普通函數,函數指標將傳遞給函數模板。傳統上,編譯器在透過函數指標進行內聯呼叫時遇到困難。

為了說明這個概念,請考慮以下函數模板:

template 
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* begin, int* end, _some_lambda_type f) {
    for (; begin != end;   begin)
        *begin = f.operator()(*begin);
}

在這種情況下,編譯器可以存取 _some_lambda_type::operator() 並且可以無縫地內聯調用它。每個 lambda 都有不同的類型,因此在 map() 中使用不同的 lambda 將產生新的實例化。

但是,如果使用函數指標:

map(int* begin, int* end, int (*f)(int)) {
    for (; begin != end;   begin)
        *begin = f(*begin);
}

編譯器將無法內聯對 f 的調用,直到對 map() 的包含調用也被內聯,從而允許它精確定位特定函數。這凸顯了 lambda 在編譯器最佳化方面相對於普通函數的優勢。

最新教學 更多>
  • 如何使用系統憑證在 Go HTTP 請求中執行 NTLM 驗證?
    如何使用系統憑證在 Go HTTP 請求中執行 NTLM 驗證?
    使用系統憑證的Go HTTP 請求中的NTLM 驗證在此問題中,使用者尋求有關在Go HTTP 中執行Windows NTML 驗證的指示使用呼叫使用者的系統憑證進行請求。他們提供了 C# 和 Python 的範例,示範如何在這些語言中實現此目的。 解決方案在於利用 go-ole 函式庫,該函式庫允...
    程式設計 發佈於2024-11-16
  • 如何確定我的 C/C++ 程式碼正在編譯的 CPU 架構?
    如何確定我的 C/C++ 程式碼正在編譯的 CPU 架構?
    針對特定 CPU 架構進行編譯編寫 C 或 C 程式碼時,通常需要了解您所針對的目標 CPU 架構編譯。此資訊可用於優化程式碼效能或確保與特定硬體的兼容性。不同的編譯器利用各種非標準預處理器定義來區分 CPU 架構(例如,MSVS 中的 _M_X86、GCC 中的 i386__ 和 __arm)。 ...
    程式設計 發佈於2024-11-16
  • 如何在 Python 模組中模仿類別行為?
    如何在 Python 模組中模仿類別行為?
    使用getattr在模組中動態實現類別行為在某些情況下,可能需要模仿_ _getattr__ 對類別的行為,但對整個模組的行為。這允許動態創建類別實例並根據模組上的屬性查找呼叫其方法。 但是,嘗試直接在模組上定義 __getattr__ 方法面臨兩個障礙:Python 只檢查類別上的此類方法。 修改...
    程式設計 發佈於2024-11-16
  • 如何在 Python 中建立真正獨立的物件副本?
    如何在 Python 中建立真正獨立的物件副本?
    在Python 中複製物件:綜合指南創建物件的副本是Python 程式設計中的一項基本任務,尤其是在處理複雜資料時結構。本文深入研究了 Python 中物件複製的複雜性,特別關注創建不受原始物件變更影響的獨立物件。 淺複製和深複製在Python中,複製物件有兩種主要方法:淺複製和深複製。淺複製會建立...
    程式設計 發佈於2024-11-16
  • 如何從 PHP 中的 SimpleXMLElement 擷取內部 XML 內容?
    如何從 PHP 中的 SimpleXMLElement 擷取內部 XML 內容?
    PHP SimpleXML:存取內部 XML在 PHP XML 解析領域,SimpleXML 擴充功能可讓開發人員輕鬆操作 XML 文件。然而,提取 XML 元素的內部內容(排除周圍的元素標籤)可能具有挑戰性。 考慮以下 XML 片段:<qa> <question>Who...
    程式設計 發佈於2024-11-16
  • Java 中的哪一種字串連線選項最適合您?
    Java 中的哪一種字串連線選項最適合您?
    理解Java 中的字串連接選項: 、 StringBuilder 和concat 在Java 中,有多種連接字串的選項:使用' ' 運算子、StringBuilder 類別或'concat' 方法。每個選項都有其優點和用例,我們將在下面探討。 何時使用 ' &...
    程式設計 發佈於2024-11-16
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-11-16
  • 如何在Ubuntu上不輸入密碼安裝MySQL?
    如何在Ubuntu上不輸入密碼安裝MySQL?
    Ubuntu上的無密碼MySQL安裝問題:Ubuntu上的無密碼MySQL安裝問題:如何在Ubuntu上安裝MySQL而無需在過程中輸入密碼? 背景:使用 sudo apt-get install mysql 安裝 MySQL 提示輸入密碼,可能不方便在非互動式場景或編寫安裝腳本時。 #!/bin/...
    程式設計 發佈於2024-11-16
  • Go 的 DNS 解析功能是否具有快取查找功能?
    Go 的 DNS 解析功能是否具有快取查找功能?
    Go 的 DNS 解析功能有快取查找嗎? Go 程式語言的標準函式庫缺乏透過 dnsclient 快取 DNS 尋找的內建機制。雖然快取 DNS 回應可以透過減少昂貴的 DNS 查詢數量來顯著提高應用程式的效率,但 Go 目前不提供此功能。 替代緩存解決方案由於 Go 不提供原生 DNS 緩存,因此...
    程式設計 發佈於2024-11-16
  • 如何解決Java Web應用程式中的「java.lang.UnsatisfiedLinkError no *.dll in java.library.path」?
    如何解決Java Web應用程式中的「java.lang.UnsatisfiedLinkError no *.dll in java.library.path」?
    疑難排解「java.lang.UnsatisfiedLinkError no *.dll in java.library.path」問題應用程式使用System.loadLibrary() 等靜態連結方法在Web 應用程式中包含自訂DLL 並不總是那麼簡單。為了有效解決「java.lang.Unsa...
    程式設計 發佈於2024-11-16
  • 如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    如何在 PHP 中組合兩個關聯數組,同時保留唯一 ID 並處理重複名稱?
    在 PHP 中組合關聯數組在 PHP 中,將兩個關聯數組組合成一個數組是常見任務。考慮以下請求:問題描述:提供的代碼定義了兩個關聯數組,$array1和$array2。目標是建立一個新陣列 $array3,它合併兩個陣列中的所有鍵值對。 此外,提供的陣列具有唯一的 ID,而名稱可能重疊。要求是建構一...
    程式設計 發佈於2024-11-16
  • 為什麼我在遷移到 AngularJS 1.3 時會收到「[$injector:modulerr]」?
    為什麼我在遷移到 AngularJS 1.3 時會收到「[$injector:modulerr]」?
    AngularJS:遷移到V1.3 時遇到[$injector:modulerr]在AngularJS 程式碼中,您遇到錯誤遷移程式碼到版本1.3 時:未捕獲錯誤:[$injector:modulerr]。要理解這個問題,需要注意的是,在 AngularJS 1.3 及更高版本中,全域控制器函數宣告...
    程式設計 發佈於2024-11-16
  • 如何解決MySQL中的「1418 (HY000) This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its statements and binarylogging isenabled\」錯誤?
    如何解決MySQL中的「1418 (HY000) This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its statements and binarylogging isenabled\」錯誤?
    匯入MySQL資料庫時,可能會遇到錯誤「1418 (HY000) at line 10185: This function has none of DETERMINISTIC, NO SQL, 或 READS SQL DATA in its statements and二進位日誌記錄已啟用(您可能想...
    程式設計 發佈於2024-11-16
  • 如何在 MySQL 中以特定格式(如“d-m-Y”)顯示日期?
    如何在 MySQL 中以特定格式(如“d-m-Y”)顯示日期?
    MySQL 日期格式和表示方法在MySQL 中建立DATE 欄位時,使用者可能會遇到日期儲存在非使用者中的問題- 友善的格式,如0000-00-00。本文討論了將此格式變更為「d-m-Y」或任何其他首選顯示格式的可能性。 MySQL 的內部日期儲存MySQL 在內部將日期儲存為三-按照特定公式打包的...
    程式設計 發佈於2024-11-16
  • 為什麼我的 PyQt4 按鈕點擊訊號在循環內總是輸出相同的值?
    為什麼我的 PyQt4 按鈕點擊訊號在循環內總是輸出相同的值?
    在循環中連接 PyQt4 中的槽和訊號在 PyQt4 中,在槽和訊號之間建立連接是事件處理的基本面向。但是,當嘗試連接循環內按鈕發出的多個訊號時,可能會出現意外行為。 為了說明此問題,請考慮以下程式碼:def __init__(self): for i in range(0, 10): ...
    程式設計 發佈於2024-11-16

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3