“const unordered_map”编译速度慢作为全局变量
我的编译时间非常慢,可能是由于存在 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
中有地图的内容:
#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
是一个函数指针EMPTYCHAR
,并且所有corr::something
类型的变量都是整数,因此它们定义了键值字符串
我遇到的问题是,每个包含 correspondace.h 的文件的 makefile 需要 10 分钟,因为确实有很多行代码需要处理。
您可能已经了解,需要此映射来允许用户在不知道函数名称的情况下仅使用字符串来访问函数。因此,我目前无法消除此功能,因为它是基础功能。
尽我所能,我尝试将此文件包含在尽可能少的文件中。无论如何,不可避免地将它包含在将生成可执行文件的每个文件中,因此,总的来说,这迫使我每次必须调试某些内容时都要等待很长时间。
如果您对如何加快编译速度并保持此功能有任何建议,这对我来说真的很有帮助:)
I am experiencing really slow compilation time, probably due to the existence of a global variable of the kind std::unordered_map
. Below you can find the lines of code, which are located in a file called 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
and, in map_content.h
there is the content of the 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}},\
...
it goes on like this for about 3500 lines.
Note that
Cfptr_t
is a function pointerEMPTYCHAR
and all the variables of the typecorr::something
are integers, so they define the key value string
The problem I encounter is that the makefile takes 10 minutes for each file that includes correspondace.h
, since indeed there are so many lines of code to process.
As you may have understood, this map is needed to allow the user to access functions without knowing their names, but just with a string. For this reason I cannot at the moment eliminate this feature, since it's fundamental.
As far as I could do, I tried to include this file in as few files as possible. Anyways, it is inevitable to include it in every file that will generate the executable, so, overall, this forces me to wait a long time each time I have to debug something.
If you have any suggestion on how to speed up compilation keeping this feature, it would be really helpful for me :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更改
为
新的
.cpp
文件:这将导致仅发出映射的一个定义(与
inline
相比,它将在每个翻译单元 odr 中发出) -使用它)。只要在进入
main
之前构造另一个静态存储持续时间对象期间不使用映射,它就是安全的。如果需要的话,最好将映射设置为函数中的局部静态变量,通过引用返回它以供调用者使用。这将避免“静态初始化顺序惨败”。它还可能有助于创建一个函数,为每个条目使用按值,然后:
insert
语句初始化映射,而不是在初始化程序中完成所有操作,即有一个函数initSquaredampl
返回 < code>std::unordered_map这可能有帮助,因为编译器可能未针对编译很长的表达式进行优化,或者初始化器。然而,他们也可能在处理很长的函数时遇到问题。
Change
to
and in a new
.cpp
file:This will cause only one definition of the map to be emitted (in contrast to
inline
which will emit it in every translation unit odr-using it).It is safe as long as the map isn't used during the construction of another static storage duration object before
main
is entered. If that is required, it would be preferable to make the map a local static variable in a function returning it by-reference to be used by callers. This would avoid the "static initialization order fiasco".It might also help to make a function to initialize the map with an
insert
statement for each entry instead of doing it all in the initializer, i.e. have a functioninitSquaredampl
returning astd::unordered_map<std::string, Entry_t>
by-value and then:This may help, because a compiler might not be optimized for compilation of very long expressions or initializers. However, they may also have trouble with very long functions.
我要感谢@Kaldrr 和@user17732522 的精彩见解。我通过以下方式解决了我的问题。在 correspondance.h 中,我刚刚输入:
即空地图的简单初始化。
然后,我创建了一个新的标头
init_map.h
,其中包含以下几行:当然,还有一个相应的
initialise_map.cpp
文件,其中包含函数的定义,其中
map_content_body.h
是地图内容的行。通过这种方式:initialise_map.o
,所有将生成可执行文件的 .cpp 文件将不包含代码,但该函数将在链接阶段存在因此,除非我删除
initialise_map.o
或更新initialise_map.cpp
,否则我的代码将在一个正常的速度,理应如此。当然,我在每个头文件中都添加了
#pragma Once
或类似内容,以避免无用的代码复制。也非常感谢@JaMiT 的鼓励的话:)
编辑:正如我在评论中建议的那样,我最终实现了@user17732522 的解决方案。这样我就不必每次都调用函数来进行初始化。
I want to thank @Kaldrr and @user17732522 for the nice insights. I solved my problem in the following way. In
correspondance.h
I just put:i.e. a simple initialisation of the empty map.
Then, I created a new header
init_map.h
with the following lines:and, of course, a correspondant
initialise_map.cpp
file with the definition of the functionwhere
map_content_body.h
are the lines of the content of the map. In this way:initialise_map.o
, all the .cpp files that will generate the executable will not contain the code, but the function will be there in linking phaseAs a result, unless I remove
initialise_map.o
or I updateinitialise_map.cpp
, my code compiles at a normal speed, as it should be.Of course, I took care of having a
#pragma once
or similar in each header file to avoid useless code copies.Many thanks also to @JaMiT for the encouraging words :)
EDIT : As I was suggested in the comments, I eventually implemented the solution by @user17732522. In this way I don't have to call a function each time to do the initialisation.