4

我在这个主题上找到了一个类似的帖子,但它涉及设计方面而不是性能,所以我发布这个是为了了解大 c 文件的破坏如何影响编译和执行时间。

我有一个很大的 utils 文件(我们都知道它们会很快增长)。我试图了解将文件拆分为基于模块的函数文件(cookies.c、memcacheutils.c、stringutils.c、search.c、sort.c、arrayutils.c 等)是否会增加编译和执行时间的任何损失.

我的常识是它会增加一些惩罚,因为代码现在必须在远取位置而不是在同一个文件中找到指针。

我可能大错特错或部分正确。寻求所有大师的指导。我当前的 utils 文件大约 150k,包含 80 多个函数。

感谢您阅读帖子。

4

6 回答 6

4

通常将您的项目分成多个编译单元可以更好地进行项目管理和更快的部分编译。当您编辑一个文件时,您只需要重新编译该编译单元并重新链接即可进行测试和调试。

取决于您的编译器,尽管将所有内容放在一个文件中可能会允许额外的内联和功能优化。一切都以编译时间为代价。

于 2013-07-04T11:20:34.270 回答
3

您应该始终将您的来源分割成逻辑单元。

这还具有编译速度更快的好处,因为您不需要为每次更改都重新编译所有内容。维护这样的来源充其量也是可怕的,并且跟踪生产相关的变化也是有问题的。

如果一个函数驻留在不同的模块中,则没有性能增益/惩罚,最坏的情况是它会是一条额外的 jmp 指令。如果你的代码真的依赖机器周期,那么你应该首先开始考虑算法的设计。

于 2013-07-04T11:20:19.813 回答
3

当您拥有具有不同段的 16 位 PC 时,这曾经很重要。远(更糟糕的是,“巨大的”)指针会带来性能成本,因为您不得不开始使用段寄存器。

如今,使用 32 位寻址应该没有成本。最终,如果您担心性能,那么您开始考虑汇编中的“跳转表”,它要求目标地址相对于当前指令距离很近。

那么,在 C 语言中,您确实应该将您的代码放在不同的模块中(阅读有关软件“内聚”和“耦合”理论问题的信息)。执行时间应该没有差异。就编译时间而言,它“取决于” - 特别是如果您重复包含文件。在具有多个文件的大型项目中,可以节省大量时间,因为您只能重新编译已更改的代码单元。在一个小项目中编译时间是如此之小以至于对效率的担忧相对微不足道。

于 2013-07-04T11:20:42.333 回答
2

编译时间会改变。

(注意——任何可以进行增量构建的系统和项目都会变得更快。)

如果除了吐入文件之外没有对代码进行任何更改,那么最终结果就不会改变。

如果您在代码中包含调试信息,那么您的最终代码结果会随着更多文件而改变,但我不希望出现性能差异。


旁注,我认为没有一个曾经使用过大型系统的程序员会告诉您不要拆分文件。为了使大型系统可维护,您只需要这样做。不能说你的系统是否已经到了那个时候,但是早点做是没有坏处的。拆分文件。

于 2013-07-04T11:19:48.610 回答
1

这不会增加任何性能损失。即使这样做了,这也是一个过早的优化。唯一重要的是开发时间。

如果您发现您已经确保所有算法都具有最佳复杂性,调整了所有内部循环以获得最佳性能,并且仍然需要将运行时间缩短几皮秒,那么您始终可以创建一个源#include文件拆分源将它们作为一大块提供给编译器。

于 2013-07-04T11:44:04.677 回答
0

关于运行时性能,我会考虑运行一些性能测量,这取决于您对性能损失的敏感程度。到目前为止,答案的共识是运行时性能不会因将文件拆分为更小的单元而降低,但这取决于您对“性能”的定义。

如果你真的很担心最轻微的性能损失,除非你启用了整个程序优化,并且它是有效的,如果你的文件被拆分,编译器可能会错过一些优化机会(当然取决于代码风格、全局变量的使用、内联的使用(请记住,在某些情况下,不内联可能会产生更好的结果)、静态类/方法(如果您使用的是 c++ 等)。

我怀疑在某些极端情况下,拥有单个源文件可能会带来微小的性能改进(而在其他情况下,它可能会降低性能!)。在几个简单的场景之前和之后进行测试,包括改变编译器的优化级别,将是一个非常有趣的实验。

我认为您不会找到任何硬性规定,例如“将大量相关函数拆分为两个源文件总是可以的”,但您可能会发现对于特定的编译器设置和源文件,拆分up 文件甚至可能导致影响指令缓存性能的微妙之处(取决于性能测试的细粒度)。

于 2013-07-04T13:29:02.800 回答