在C中将单个文件拆分为多个文件-性能方面

在C中将单个文件拆分为多个文件-性能方面,c,performance,C,Performance,我发现了一篇关于这个主题的类似文章,但它涉及的是设计方面,而不是性能,所以我发布这篇文章是为了理解一个大c文件的中断是如何影响编译和执行时间的 我有一个很大的utils文件(我们都知道它们增长很快)。我试图理解将文件拆分为基于模块的函数文件(cookies.c、memcacheutils.c、stringutils.c、search.c、sort.c、arrayutils.c等)是否会增加编译和执行时间 我的常识是,这会增加一些惩罚,因为代码现在必须在较远的获取位置而不是在同一个文件中查找指针

我发现了一篇关于这个主题的类似文章,但它涉及的是设计方面,而不是性能,所以我发布这篇文章是为了理解一个大c文件的中断是如何影响编译和执行时间的

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

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

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


谢谢你阅读这篇文章

编译时间会改变

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

如果除了插入文件外,代码没有任何更改,那么最终结果不会更改

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



顺便说一下,我不认为有一个程序员在使用大型系统时会告诉你不要分割文件。为了使大型系统可维护,您只需这样做。我不能说你的系统是否已经达到了这个程度,但是尽早这样做并没有什么坏处。分割文件。

您应该始终将源分割为逻辑单元

这也有加快编译速度的好处,因为您不需要为每一次更改重新编译所有内容。此外,维护这样一个源代码充其量也很糟糕,跟踪与生产相关的更改也很成问题


如果函数驻留在不同的模块中,则不会有性能增益/惩罚,最坏情况下,它将是一条单独的附加jmp指令。如果您的代码确实依赖于机器周期,那么您应该首先考虑算法的设计。

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


根据您的编译器,尽管在一个文件中包含所有内容可能会允许额外的内联和功能优化。所有这一切都是以编译时间为代价的。

当您拥有具有不同段的16位PC时,这一点曾经很重要。远(更糟糕的是,“”)指针带来了性能成本,因为您必须开始胡闹段寄存器

如今,32位寻址应该没有成本。最后,如果你担心性能,那么你就开始考虑汇编中的“要求目标地址相对于当前指令短的距离”。
那么,在C语言中,您真的应该将代码放在不同的模块中(阅读软件“内聚”和“耦合”理论问题)。执行时间应该没有差别。就编译时间而言,这“取决于”-尤其是在重复包含文件的情况下。在一个大型项目中,有多个文件可以节省大量时间,因为您只能重新编译更改过的代码单元。在一个小项目中,编译时间很短,因此不必担心效率。

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


如果您发现您已经确保所有算法具有最佳复杂度,调整所有内部循环以获得最佳性能,并且仍然需要在运行时减少几皮秒,您可以创建一个源代码文件,它将简单地将代码< <代码>包含所有的拆分源作为一个大的块提供给编译器。

< P>关于运行时的性能,我将考虑运行一些性能测量,这取决于在性能损失方面您需要多敏感。到目前为止,答案中的共识是,将文件拆分为更小的单元不会降低运行时性能,但这取决于您对“性能”的定义

如果您真的担心最轻微的性能损失,除非您启用了,并且它是有效的,那么如果您的文件被拆分,编译器很可能会错过一些优化的机会(当然,这取决于代码的样式、全局函数的使用、内联函数的使用)(记住,在某些情况下,不内联可能会产生更好的结果),如果使用C++等,则可以使用静态类/方法。 我怀疑在某些边缘情况下,拥有一个源文件可能会带来边际性能改进(在其他情况下,它可能会降低性能!)。在几个简单场景之前和之后进行测试,包括改变编译器的优化级别,将是一个非常有趣的实验


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

您必须估算项目的性能时间损失与开发时间损失。将大文件拆分为小文件通常会增加一个或多个级别的指针间接寻址,但为了可维护性,可以简化开发人员或维护人员的工作。将这个庞然大物切碎!Microsoft Windows项目就是其中之一如果没有h,必须为每个文件导入
windows.h
,可能会花费很长时间