【问题标题】:Performance with non executed code未执行代码的性能
【发布时间】:2014-09-03 07:52:43
【问题描述】:

也许,我的问题很愚蠢,但我没有找到任何答案,我真的很想知道它。当我们有未调用函数的程序时(例如,它们仅为将来的实现做准备),我认为编译器也会读取这些行(最少函数声明)。没问题,但是在更大的项目中表现如何?有什么我们应该避免的(例如一些分配/包含文件)影响更大的事情吗?

例如:

//never called/used
class abc{
...
}

//never called/used
float function_A(float x, int y){

...}

int main(){
...
}

这只是一个简短的例子,但我想每个人都知道我的意思。 非常感谢!

【问题讨论】:

  • 定义“性能”。
  • 这称为dead code,通常被认为是不好的做法。然而,在很多情况下它是不可避免的(例如标准 STL 实例化......)。如果编译器优化得很好,它将删除死代码。
  • 例如应用程序运行时间,内存使用,...有很多点。我只是想知道它如何影响您的应用程序,以及是否有一些有问题的部分最好避免。

标签: c++ performance optimization


【解决方案1】:

编译器的当前实现不会为某些函数生成代码,您可以阅读here。未使用的代码通常不会影响性能,尤其是在您声明但未定义函数的情况下。只有带有大量指令的函数才会影响性能,因此我建议您阅读instruction caching

在更大的库中,您应该关心包含文件。如果您使用并(更重要的是)智能地包含它们,您可以在编译时获得性能。即在头文件中使用前向声明,并在 cpp 文件中包含头文件。 另一件事是,如果您拆分为几个头文件,编译器可以在链接时跳过整个 .o 文件(编译器在编译期间创建的文件)(如果不使用它们)。 希望对你有所帮助

【讨论】:

  • 拆分头文件不会影响目标文件。这是对源代码的预处理步骤。
  • 如您所说,它不会影响目标文件,但会影响链接器处理它们的行为
  • 类型或函数定义或前向声明不会使其引用函数/类/任何内容。因此,它通常不会影响链接器。一个例外是它实际上声明了一个类的实例,这通常不是在头文件中完成的。我能想到的另一个例外是使用 #pragma comment(lib...) 之类的东西,但这是特定于编译器的。
  • 感谢大家提供有用的 cmets 和链接。我将不得不阅读更多关于此的内容。
【解决方案2】:

如果您指的是应用程序性能,则保留未使用的代码不会产生任何影响。编译器会消除死代码。但是必须通过更多的代码,编译器会稍微变慢,所以你将不得不等待更长的时间来编译程序。不包括未使用的头文件是个好主意,因为一个头文件可以拉入数十或数百个其他头文件。 (但预编译的头文件也可以帮助解决这个问题。)

【讨论】:

    【解决方案3】:

    如果未删除的死代码降低了整个程序的局部性,指令缓存可能仍然是一个问题。

    想象两个函数 A 和 B,其中 B 被 A 反复调用。如果 A 和 B 适合同一缓存行,则从 A 调用 B 不太可能产生缓存未命中。但是,如果链接器在两个函数之间放置了第三个函数,从而使 A 和 B 不再位于同一缓存行上,则调用 B 时缓存未命中的可能性变得更大,从而降低了整体执行速度。

    虽然效果可能无法很好地衡量并且取决于许多其他因素,但减少死代码通常是一个好主意。

    【讨论】:

      【解决方案4】:

      如果编译器可以将其检测为死代码,它将完全删除它并可能会打印一个警告。如果不是,它将增加目标代码大小。使用静态链接,链接器将删除未使用的函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 2014-06-29
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 2012-03-30
        • 1970-01-01
        相关资源
        最近更新 更多