[英]Slow compilation speed for "const unordered_map" as global variable
我的編譯時間非常慢,可能是由於存在std::unordered_map
類型的全局變量。 您可以在下面找到代碼行,它們位於名為correspondance.h
的文件中
using Entry_t = std::tuple<Cfptr_t, short int, short int>;
...
#include "map_content.h"
inline const std::unordered_map<std::string, Entry_t> squaredampl{MAP_CONTENT};
#undef MAP_CONTENT
並且,在map_content.h
中有 map 的內容:
#define MAP_CONTENT \
{ {EMPTYCHAR+corr::su_R,ANTICHAR,EMPTYCHAR+corr::sd_L,EMPTYCHAR+corr::A,EMPTYCHAR+corr::W},{ &mssm2to2::sumSqAmpl_su_R_anti_sd_L_to_A_W, 9,2}},\
{ {EMPTYCHAR+corr::su_L,ANTICHAR,EMPTYCHAR+corr::sd_R,EMPTYCHAR+corr::A,EMPTYCHAR+corr::W},{ &mssm2to2::sumSqAmpl_su_L_anti_sd_R_to_A_W, 9,2}},\
...
它像這樣持續了大約 3500 行。 注意
Cfptr_t
是一個function指針EMPTYCHAR
和corr::something
類型的所有變量都是整數,所以它們定義了鍵值字符串我遇到的問題是 makefile 每個包含correspondace.h
的文件需要 10 分鍾,因為確實有很多代碼行要處理。
正如您可能已經理解的那樣,需要這個 map 來允許用戶在不知道函數名稱的情況下訪問函數,而只需要一個字符串。 出於這個原因,我目前無法消除此功能,因為它是基本功能。
盡我所能,我嘗試將此文件包含在盡可能少的文件中。 無論如何,將它包含在每個將生成可執行文件的文件中是不可避免的,因此,總的來說,這迫使我每次必須調試某些東西時都要等待很長時間。
如果您對如何加速編譯保持此功能有任何建議,那對我來說真的很有幫助:)
改變
#include "map_content.h"
inline const std::unordered_map<std::string, Entry_t> squaredampl{MAP_CONTENT};
#undef MAP_CONTENT
到
extern const std::unordered_map<std::string, Entry_t> squaredampl;
在一個新的.cpp
文件中:
#include "correspondance.h"
#include "map_content.h"
const std::unordered_map<std::string, Entry_t> squaredampl{MAP_CONTENT};
#undef MAP_CONTENT
這將導致僅發出 map 的一個定義(與內聯相反, inline
將在每個翻譯單元 odr-using 中發出它)。
只要 map 在進入main
之前的另一個 static 存儲持續時間 object 的構造期間不被使用,它就是安全的。 如果需要,最好使 map 成為 function 中的本地 static 變量,通過引用返回它以供調用者使用。 這將避免“靜態初始化順序慘敗”。
它也可能有助於制作一個 function 來初始化 map 每個條目的insert
語句而不是在初始化程序中完成所有操作,即有一個 function initSquaredampl
返回一個std::unordered_map<std::string, Entry_t>
按值然后:
auto initSquaredampl() {
std::unordered_map<std::string, Entry_t> squaredampl;
// Insert items one-by-one
return squaredampl;
}
const std::unordered_map<std::string, Entry_t> squaredampl = initSquaredampl();
這可能會有所幫助,因為編譯器可能不會針對非常長的表達式或初始化程序的編譯進行優化。 然而,他們也可能在處理非常長的函數時遇到麻煩。
我要感謝@Kaldrr 和@user17732522 的精彩見解。 我通過以下方式解決了我的問題。 在correspondance.h
我只是把:
inline std::unordered_map<std::string, Entry_t> squaredampl;
即空 map 的簡單初始化。然后,我使用以下幾行創建了一個新的 header init_map.h
:
#include "correspondance.h"
int Initialise();
當然,還有一個相應的initialise_map.cpp
文件,其中定義了 function
#include "initialise_map.h"
int Initialise()
{
if (!corr::squaredampl.empty()) return 0;
corr::squaredampl.reserve(3500);
corr::squaredampl = {
#include "map_content_body.h"
};
return 0;
}
其中map_content_body.h
是map的內容行。這樣:
initialise_map.o
,所有將生成可執行文件的 .cpp 文件將不包含代碼,但 function 將在鏈接階段存在因此,除非我刪除initialise_map.o
或更新initialise_map.cpp
,否則我的代碼會以正常速度編譯,因為它應該是這樣。
當然,我注意在每個 header 文件中使用#pragma once
或類似的代碼以避免無用的代碼副本。
也非常感謝@JaMiT 的鼓勵話語:)
編輯:正如我在評論中所建議的那樣,我最終通過@user17732522 實現了解決方案。 這樣我就不必每次都調用 function 來進行初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.