编译时间和内存 大型C++项目的使用情况?
Compile Time & Memory Usage of a large C++ Project?
假设一个人有大约50,000个不同的.cpp
文件。
每个.cpp
文件只包含一个类,其中包含大约 ~1000 行代码(代码本身并不复杂 - 涉及矩阵和向量的内存中操作 - 即不使用特殊库(。
我需要构建一个项目(在Linux
环境中(,该项目必须导入和使用所有这些 50,000 个不同的.cpp
文件。
我想到了几个问题:
- 编译它大约需要多长时间?编译文件的大致大小是多少? 有什么更好的方法 - 保留 50,000 个不同的
.so
文件(编译扩展(,并让主程序逐个导入它们,或者将这 50,000 个不同的.cpp
文件合并到一个大的.cpp
文件中,然后处理它? 哪种方法会更快/更有效?
任何见解都会得到极大的赞赏。
没有答案,只有建议。
马上回头看你:你到底想做什么?您是否正在尝试从不同的源文件创建代码库? 或者这是一个可执行文件? 你真的编码了那么多.cpp文件吗?
50,000 个源文件很好...一个大型项目。 您是否尝试在所有文件中执行一些共同的操作(例如,每个源文件都表示资源,记录,图像或独特的内容(。或者它只是 50K 不同的代码文件?
大部分编译时间不会基于每个源文件的大小。它将基于每个 cpp 文件将引入的头文件(以及它们包含的头文件(的数量。 标头虽然通常不包含实现,但仅包含声明,但必须经过编译过程。 代码库中的冗余标头可能会减慢构建时间。
这种规模的大型项目使用预编译的标头。 您可以将所有常用的头文件包含在一个头文件 (common.h( 中并构建 common.h。 然后所有其他源文件只包含"common.h"。 编译器可以配置为在看到每个源的 #include"common.h"时自动使用已编译的头文件。
(i( 确定这一点涉及太多因素,甚至不可能进行近似。编译可以是内存、CPU 或硬盘驱动器。文件的复杂性很重要(从您的描述来看,您的复杂性很低(。
(ii( 这样做的典型方法是创建一个库,让系统弄清楚链接或加载。您可以选择静态或动态链接。
静态链接
假设您使用的是 gcc,这看起来像这样:
g++ -c file1.cpp -o file1.o
g++ -c file2.cpp -o file2.o
...
g++ -c filen.cpp -o filen.o
ar -rc libvector.a file1.o file2.o ... filen.o
然后,当您构建自己的代码时,您的最终链接如下所示:
g++ myfile.cpp libvector.a -o mytask
动态链接
同样,假设您使用的是 gcc,这看起来像这样:
g++ -c file1.cpp -fPIC -o file1.o
g++ -c file2.cpp -fPIC -o file2.o
...
g++ -c filen.cpp -fPIC -o filen.o
ld -G file1.o file2.o ... filen.o -o libvector.so
然后,当您构建自己的代码时,您的最终链接如下所示:
g++ myfile.cpp libvector.so -o mytask
您需要 libvector.so 位于加载程序的路径中,可执行文件才能正常工作。
无论如何,只要 50,000 个文件不更改,您只需要执行最后一个命令(这会快得多(。
您可以从".cpp"构建每个对象文件,让".h"文件具有大量(我的意思是很多(前向声明 - 因此当您更改.h
文件时,它不需要重新编译程序的其余部分。通常,函数/方法需要其参数中的对象名称或它正在返回的内容。如果它需要其他细节 - 是的,它需要包括在内。
请得到斯科特迈尔斯的书 - 会帮助你很多。
哦 - 当试图吃一个大蛋糕时 - 把它分开。切片更易于管理。
我们真的不能说编译需要多少时间,但你应该做的是将每个.cpp
/.h
对编译成一个.o
文件:
$ g++ -c -o test.o test.cpp ...
一旦你有了所有这些,你编译主程序如下:
$ g++ -c -o main.o main.cpp
$ g++ -o main main.o test.o blah.o otherThings.o foo.o bar.o baz.o etc...
你使用.so
的想法几乎是在问"我能多快崩溃程序,可能还有操作系统?共享库适用于数量较少的大型库,而不是链接到二进制文件的 50,000 .so
(特别是如果您动态加载它们......那将是 BAD(。
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 在集合的情况下使用emplace_hint的用例是什么?
- 在没有堆的情况下用两种方法构造对象
- 如何在不中断的情况下正确使用C++中的切换用例语句中的Fallthrough
- 给定一个填充无符号字符**的 C 函数,如何在没有中间副本的情况下用数据填充 std::vector
- 在这种情况下,有没有办法用单个解决方案替换两个仅在类型上不同的相似函数?
- 为什么在一种情况下,我会收到带有字符串文字的已弃用转换警告,而在另一种情况下却没有?
- 不能在没有对象的情况下调用成员函数,但我用对象调用函数
- 在不先显式调用析构函数的情况下,在旧对象上使用placement new是否危险
- 无法在前面有多余空格的情况下获取要打印的数组.只有第一个值会用空格打印
- 在可疑的情况下发出叮当警告:函数'foo'可以用属性"noreturn"声明吗?
- 如何在没有任何JavaScript知识的情况下用PNaCl编写C++HTML5应用程序
- 如何在不使用开关大小写的情况下用C++编写菜单驱动的程序
- 在什么情况下,运算符=应该用左值/右值重载而不是复制和交换来实现
- 在没有测试用例的情况下提升单元测试框架
- 在这种情况下,为函数赋值有什么用
- 如何在没有_setmode的情况下用C++输出unicode
- 如何在没有STL的情况下用c++中的Key创建和访问内存块
- 如何在不锁定文件的情况下用C++编写文件
- clang与gcc运行时的区别:用clang构建的c++类模板在没有复制构造函数的情况下崩溃,用复制构造函数构建的gcc