与传统的头文件相比,c++20 中的模块会减少编译时间吗?
Will modules in c++20 reduce compile time compared to traditional header-files?
假设我们有模块接口源文件foo.ixx,其中定义了模块foo。我们使用
import foo;
在许多不同的 cpp 文件中。与许多不同的 cpp 文件中包含传统头文件 foo.h 的情况相比,编译时间会减少吗?如果减少编译时间,为什么会这样?
"从实现文件访问头文件的机制是使用来自 C 预处理器的 include 指令。换句话说,你的头文件被隐式复制了很多次。
一个项目中所有头文件的副本很多,编译器不得不一遍又一遍地遍历和解析。最明显的问题之一是代码编译时间。
模块有效地替换了头文件和预处理器包含指令。模块提出的解决方案表明我们摆脱了 C 预处理器的文本包含,因此摆脱了它的所有缺点。”[每个模块只处理一次。参见 Table 2]
是的,模块的优点之一是可以减少编译时间。为了进行比较,这是今天的完成方式:
// foo.hpp
// some code
// a.cpp
#include "foo.hpp"
// b.cpp
#include "foo.hpp"
现在,当编译 2 个翻译单元 a.cpp
和 b.cpp
时,some code
被文本包含到这些源文件中,因此 some code
被编译了两次。虽然链接器会注意最终的可执行文件中实际上只有一个定义,但编译器仍然需要编译 some code
两次,这是浪费精力。
有了模块,我们会有类似的东西:
// foo.hpp
export module foo;
// some code
// a.cpp
import foo;
// b.cpp
import foo;
现在编译过程不一样了;有一个中间阶段,foo.hpp
被编译成 a.cpp
和 b.cpp
可以使用的格式,这意味着实现文件不需要编译 some code
,他们可以直接使用 some code
中的定义。
这意味着 foo.hpp
只需要编译一次,这可能会大大减少编译时间,尤其是随着使用模块接口单元的实现文件数量的增加。
Header 包含机制依赖于文本预处理(本质上类似于解释脚本语言);这是 time-consuming 并且由于程序员的错误而难以追踪的错误。
另一方面,模块导入机制是一种更智能的分离接口和实现的机制,可以更好地保证一致性和正确性。它提供了在同一个翻译单元中定义接口和实现的方法,从而可以将两者匹配并通知 lib 开发人员传统包含系统中不会注意到的错误。因此,不仅构建时间,而且整个开发周期都显着缩短。
假设我们有模块接口源文件foo.ixx,其中定义了模块foo。我们使用
import foo;
在许多不同的 cpp 文件中。与许多不同的 cpp 文件中包含传统头文件 foo.h 的情况相比,编译时间会减少吗?如果减少编译时间,为什么会这样?
"从实现文件访问头文件的机制是使用来自 C 预处理器的 include 指令。换句话说,你的头文件被隐式复制了很多次。
一个项目中所有头文件的副本很多,编译器不得不一遍又一遍地遍历和解析。最明显的问题之一是代码编译时间。
模块有效地替换了头文件和预处理器包含指令。模块提出的解决方案表明我们摆脱了 C 预处理器的文本包含,因此摆脱了它的所有缺点。”[每个模块只处理一次。参见 Table 2]
是的,模块的优点之一是可以减少编译时间。为了进行比较,这是今天的完成方式:
// foo.hpp
// some code
// a.cpp
#include "foo.hpp"
// b.cpp
#include "foo.hpp"
现在,当编译 2 个翻译单元 a.cpp
和 b.cpp
时,some code
被文本包含到这些源文件中,因此 some code
被编译了两次。虽然链接器会注意最终的可执行文件中实际上只有一个定义,但编译器仍然需要编译 some code
两次,这是浪费精力。
有了模块,我们会有类似的东西:
// foo.hpp
export module foo;
// some code
// a.cpp
import foo;
// b.cpp
import foo;
现在编译过程不一样了;有一个中间阶段,foo.hpp
被编译成 a.cpp
和 b.cpp
可以使用的格式,这意味着实现文件不需要编译 some code
,他们可以直接使用 some code
中的定义。
这意味着 foo.hpp
只需要编译一次,这可能会大大减少编译时间,尤其是随着使用模块接口单元的实现文件数量的增加。
Header 包含机制依赖于文本预处理(本质上类似于解释脚本语言);这是 time-consuming 并且由于程序员的错误而难以追踪的错误。 另一方面,模块导入机制是一种更智能的分离接口和实现的机制,可以更好地保证一致性和正确性。它提供了在同一个翻译单元中定义接口和实现的方法,从而可以将两者匹配并通知 lib 开发人员传统包含系统中不会注意到的错误。因此,不仅构建时间,而且整个开发周期都显着缩短。