C语言中未使用函数的影响

C语言中未使用函数的影响,c,C,我已经用C写了一个程序,它有几个不同版本的函数。我根据硬件考虑选择要使用的函数,并在编译之前更改对此函数的单个调用。我通常也会不厌其烦地注释掉未使用的函数。但我想知道不加注释会有什么影响 在我看来,如果他们从未被调用,他们将不会对执行时间有任何影响。但它们会增加可执行文件的大小。因为可执行文件的大小很小,所以我不介意。唯一重要的是执行时间,这很关键。因此,注释掉未使用的函数似乎不值得费心。我说得对吗?代码大小决定执行速度 您可以让编译器简单地将代码作为死代码省略: 如果只从自己的编译单元内调用函

我已经用C写了一个程序,它有几个不同版本的函数。我根据硬件考虑选择要使用的函数,并在编译之前更改对此函数的单个调用。我通常也会不厌其烦地注释掉未使用的函数。但我想知道不加注释会有什么影响


在我看来,如果他们从未被调用,他们将不会对执行时间有任何影响。但它们会增加可执行文件的大小。因为可执行文件的大小很小,所以我不介意。唯一重要的是执行时间,这很关键。因此,注释掉未使用的函数似乎不值得费心。我说得对吗?

代码大小决定执行速度
您可以让编译器简单地将代码作为死代码省略:
如果只从自己的编译单元内调用函数,则在函数声明中添加
static
限定符可以让编译器知道不会从编译单元外调用它。如果编译器可以看到它没有从内部调用,它可以丢弃代码(并可能发出类似“unused function”的警告)

如果您有某种链接时间优化,它可能能够在单独的编译单元中对代码执行相同的优化,但从编译时间的角度看,这要贵一点。

代码大小影响执行速度
您可以让编译器简单地将代码作为死代码省略:
如果只从自己的编译单元内调用函数,则在函数声明中添加
static
限定符可以让编译器知道不会从编译单元外调用它。如果编译器可以看到它没有从内部调用,它可以丢弃代码(并可能发出类似“unused function”的警告)

如果您有某种链接时间优化,它可能可以在单独的编译单元中对代码执行相同的操作,但从编译时间的角度来看,这要贵一些。

好的,下面是我的计算机上的一些实际测试:

Test1.cpp:

int foo()
{
int x;
x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x;
}

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}
Test2.cpp:

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}
测试10000次(测量CPU周期):

总的来说,似乎可以实现一个小的性能提升,但我的结果是可以忽略不计的低效率。但是请记住,这是没有任何内置库的。我可以保证,它们的代码量将超过50模运算


第二部分:

Test3.cpp:

#include <stdio.h>
#include <stdlib.h>

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}

看起来编译器在处理这些方面做得相当好。在包含一些较大的库之后,它们似乎已从文件中删除。

好的,下面是我的计算机上的一些实际测试:

Test1.cpp:

int foo()
{
int x;
x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x; x = x % x;
}

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}
Test2.cpp:

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}
测试10000次(测量CPU周期):

总的来说,似乎可以实现一个小的性能提升,但我的结果是可以忽略不计的低效率。但是请记住,这是没有任何内置库的。我可以保证,它们的代码量将超过50模运算


第二部分:

Test3.cpp:

#include <stdio.h>
#include <stdlib.h>

int bar(void) {
return 0;
}

int main() {
    bar();
    return 0;
}

看起来编译器在处理这些方面做得相当好。在包含一些较大的库之后,它们似乎已从文件中删除。

如果使用优化和(MSVC)链接时优化或(GCC/Clang)-flto进行编译,则通常会删除未使用的函数,这是一个没有实际意义的问题

否则,未使用的函数对运行时性能的影响很小,甚至可能为零。它们将增加可执行文件的大小,从而增加加载时间

它们可以对性能产生任何非零影响的地方在于导致原本紧凑的代码在内存中分散。如果代码库的很大一部分是未使用/无法访问的代码,这可能会变得很明显

使用编译器指令,而不是“注释掉”例程:

#define WINDOWS_x86 0
#define WINDOWS_x64 1
#define WINDOWS_ARM 2
#define LINUX_x86 3
#define LINUX_x64 4
#define LINUX_ARM
...

#if defined(WINDOWS_x86) || defined(WINDOWS_x64)
void doAThing() {
   ULONG x = 0;
   ...
}
#elif defined(WINDOWS_ARM)
void doAThing() {
    MessageBoxA("You too cheap to buy real computer. I no calculate for joo");
}
#elif defined(LINUX_x86)
...
#endif

如果使用优化和(MSVC)链接时优化或(GCC/Clang)-flto编译,通常会删除未使用的函数,这是一个没有实际意义的问题

否则,未使用的函数对运行时性能的影响很小,甚至可能为零。它们将增加可执行文件的大小,从而增加加载时间

它们可以对性能产生任何非零影响的地方在于导致原本紧凑的代码在内存中分散。如果代码库的很大一部分是未使用/无法访问的代码,这可能会变得很明显

使用编译器指令,而不是“注释掉”例程:

#define WINDOWS_x86 0
#define WINDOWS_x64 1
#define WINDOWS_ARM 2
#define LINUX_x86 3
#define LINUX_x64 4
#define LINUX_ARM
...

#if defined(WINDOWS_x86) || defined(WINDOWS_x64)
void doAThing() {
   ULONG x = 0;
   ...
}
#elif defined(WINDOWS_ARM)
void doAThing() {
    MessageBoxA("You too cheap to buy real computer. I no calculate for joo");
}
#elif defined(LINUX_x86)
...
#endif

如果为0,则可以使用
#<代码>#endif
。因此,如果使用一系列的
#ifdef
s,可以在编译器的命令行上定义一个符号来控制编译哪个函数(这可能是一件好事,也可能不是一件好事)。如果代码中有未使用的函数导致执行时间效率低下,我想#includes会比一些额外的用户功能造成更大的问题。因为你没有发布任何代码,任何评论或回答都只是意见。如果您想知道更改对运行时性能的影响,唯一确定的方法是进行一些测试。我原以为,与手动注释代码相比,让构建系统仅包含基于编译时标志的所需函数版本是管理代码库更可靠的方法。@MikeW:真的吗?我同意唯一确定的方法是测试它,但一旦发现它确实会影响性能,那么一般情况下就不是这样了,而且可以根据机器的“能力”进行扩展。如果这在一台机器上很重要,那么在所有机器上不是都很重要吗?(当然,所有的事情都是一样的;例如,编译器设置等等)我不会叫myse