会预先编译C++标题文件会减慢链接时间?
我在外部文件中有100个.h文件。我来源中的10 .cpp文件包括这些.h文件。
因此,我从我的.cpp文件中删除了所有#include externalfiles/.* h
指令,并将它们写在我通过cmake的targe_precompile_headers($ {project_name} private PCH)中包含的pch.h标题中。 h)
。
我使用通过cmake vs 在我的.cpp文件中包括pch.h 中检查了我的构建时间。我指出了使用以下方式的构建时间: set_property(全局属性rule_launch_compile“ $ {cmake_command} -e time”)
and code>和 set_property(全局属性rule_launch_link“ $ {cmake_command} -e time”)
使用预编译的标头
[1/2]构建CXX对象CMakefiles/algocoding.dir/main。 CPP.OBJ
经过的时间:11 s。 (时间),11.413 s。 (时钟)
[2/2]链接CXX可执行algocoding.exe
经过的时间:54 s。 (时间),53.459 s。 (时钟)
构建时间包括标头
[1/2]构建CXX对象Cmakefiles/algocoding.dir/main.cpp.obj
经过的时间:14 s。 (时间),13.35 s。 (时钟)
[2/2]链接CXX可执行algocoding.exe
经过的时间:28 s。 (时间),28.109 s。 (时钟)
conlusion
从这些时间开始,似乎使用预编译的标头确实会减少.OBJ创建.cpp文件修改(main.cpp)的构建时间,但它会大大增加链接时间。
这是每个人的情况还是我在这里做错了什么?
编辑:1
实验#2 测试预编译标头的构建时间。
我试图将SPDLOG库(仅包含100个.H文件的标头库)包括在我的裸机cmake项目中(只是一个main.cpp记录1行中的文件)。两种做到这一点的方法。
- 只需将spdlog文件夹复制到我的源中,然后在main.cpp中使用#include指令
- 。 ))
构建时间结果
---- 方法1
/main.cpp.obj
[1/2]构建cxx对象cmakefiles/ test.dir :22 s。 (时间),21.904 s。 (时钟)
[2/2]链接CXX可执行式测试。exe
经过的时间:18 s。 (时间),18.311 s。 (时钟)
---- 方法2
[1/2]构建CXX对象Cmakefiles/test.dir/main.cpp.obj
经过的时间:18 s。 (时间),18.231 s。 (时钟)
[2/2]链接CXX可执行式测试。exe
经过的时间:22 s。 (时间),21.604 s。 (时钟)
结论
准则项目中的外部标题的预编译仍然给出与仅使用#include指令相同的总构建时间。当使用预编译标头时,通过链接CXX可执行文件的时间增加了构建.OBJ文件的较小时间。
我需要做些不同的事情来减少预编译外部.h文件的构建时间吗?还是这是预期的行为?
I have 100 .h files in a externalFiles diretory. Around 10 .cpp files in my source includes these .h files.
So I removed all #include externalFiles/.*h
directives from my .cpp files and wrote them in a pch.h header that I include via Cmake's target_precompile_headers(${PROJECT_NAME} PRIVATE pch.h)
.
I checked my build times using precompiled headers via Cmake vs simply including pch.h in my .cpp files. I noted build times using:set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
andset_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time")
Build time using precompiled headers
[1/2] Building CXX object CMakeFiles/AlgoCoding.dir/main.cpp.obj
Elapsed time: 11 s. (time), 11.413 s. (clock)
[2/2] Linking CXX executable AlgoCoding.exe
Elapsed time: 54 s. (time), 53.459 s. (clock)
Build time just including headers
[1/2] Building CXX object CMakeFiles/AlgoCoding.dir/main.cpp.obj
Elapsed time: 14 s. (time), 13.35 s. (clock)
[2/2] Linking CXX executable AlgoCoding.exe
Elapsed time: 28 s. (time), 28.109 s. (clock)
Conlusion
From these times it seems like using precompiled headers does reduce build time for the .obj creation of the .cpp file modified (main.cpp) but it increases the link time heavily.
Is this the case for everyone or am I doing something wrong here?
EDIT: 1
Experiment #2 to test Build times of precompiling headers.
I tried to include spdlog library(a header only library containing 100 .h files) into my bare-bones Cmake project (just a main.cpp logging 1 line into a file). Two methods of doing this.
- Just copy spdlog folder into my source and use #include directives in main.cpp
- Use precompiled headers (#include directive for spdlog in pch.h and pch.h added to project using
target_precompile_headers(${PROJECT_NAME} PRIVATE pch.h)
)
Build Time Results
----Method 1
[1/2] Building CXX object CMakeFiles/test.dir/main.cpp.obj
Elapsed time: 22 s. (time), 21.904 s. (clock)
[2/2] Linking CXX executable test.exe
Elapsed time: 18 s. (time), 18.311 s. (clock)
----Method 2
[1/2] Building CXX object CMakeFiles/test.dir/main.cpp.obj
Elapsed time: 18 s. (time), 18.231 s. (clock)
[2/2] Linking CXX executable test.exe
Elapsed time: 22 s. (time), 21.604 s. (clock)
Conclusion
Precompiling external headers in a barebones project still gives same total build time as just using #include directive. When using precompiled headers, the small time decrease in Building .obj file is compensated by increased time Linking CXX executable.
Is there something different I need to do to reduce build time when precompiling external .h files? Or is this the expected behaviour?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
clang+lld vs gcc+ld
如@HolyblackCat的建议,我尝试了 clang+lld链接器的相同汇编。对于标头文件的#include和预编译标头(〜100 .H文件)的构建时间肯定已经改善了:
从这些结果中, clang+lld的性能明显快,比GCC+ld/Gold的表现要快。此外,预编译标题在与clang+lld一起使用时设法减少了整体构建时间,因为它会减少.OBJ文件的构建时间,但设法可以达到相似的链接时间。 (有关GCC+默认链接器的构建时间,请参见问题编辑1)
@marco van de voort提到的缩放
是如何使用预编译的标头来检查.OBJ/.CPP文件的数量如何影响构建时间。因此,对于方法2(预先计的标头),我使用3个.cpp文件(缩放3 )和5 .CPP文件(缩放5 )。这是结果:
我们可以看到链接的时间增加是线性〜(9 * #cpp文件要链接到)。对于方法1,缩放会带来较差的结果。
继续前进,
尽管与Clang+lld一起使用时,预编译标题会提供更好的构建时间,但最好使用方法3。查找库版本(.lib/.dll)您只想尝试使用的标题库使用。该库是静态/动态链接的,这种方式的构建时间要快得多。
方法3:在CMAKE中使用SPDLOG库(通过VCPKG安装):
与仅使用Header libraries相比,使用.lib库版本的构建时间显着改善了使用.lib库版本(with PCH Include)(with pch insporries)
结论
Clang+LLD vs gcc+LD
As suggested by @HolyBlackCat I tried the same compilation with clang + LLD linker. The Build times have definately improved for both normal #include of header files and precompiled headers (~100 .h files):
From these results, Clang+LLD performs significantly faster than gcc+LD/gold. Moreover, precompiled headers manages to reduce overall build time when used with Clang+LLD, as it reduces build time of .obj files but manages to acheive similar linking time. (See question Edit 1, for build times of gcc+default Linker)
Scaling
Additionally, @Marco van de Voort mentioned to check how scaling the number of .obj/.cpp files using the precompiled headers affected the build times. So for Method 2(precomiled headers) I compiled with 3 .cpp files (Scaling 3) and 5 .cpp files (Scaling 5). Here are the results:
We can see the time increase in Linking is linear ~(9 * #cpp files to link to). For Method 1 scaling gives worse results.
Going Ahead
Although precompiled headers give better build times when used with Clang+LLD, its better to use Method 3. Find a library version(.lib/.dll) of the header only library you are trying to use. This library is statically/dynamically linked and the Build times are much faster this way.
Method 3: Using spdlog library in Cmake (installed via vcpkg):
Significantly improved build times of using .lib library version (with PCH includes) compared to using header only libraries (with PCH includes):
Conclusion