这些类型的变量初始化是否存在一些性能差异?

问题描述 投票:0回答:8

在局部作用域(如函数)中,给出以下 4 个示例:

(1)

int x;
int y;
// code...
x = 4;
y = 5;

(2)

int x = 4;
int y = 5;
// code...

(3)

// code...
int x = 4;
// code...
int y = 5;

(4)

// any other possibility

我声明和初始化变量的形式存在一些性能差异,或者编译为我跟踪它?

编辑

我问这个问题是因为我经常读到,最好将所有声明放在最第一行,这样对性能会更好。喜欢:

func(){
    int x,y,z,w;
    long bla,ble;
    MYTYPE weeee;
    // more declarations..
    //code..
}

但我不知道为什么。

c variables initialization
8个回答
3
投票

C 对表演只字不提。

(C99, 5.1.2.3p1) “本国际标准中的语义描述描述了与优化问题无关的抽象机的行为。”

这取决于实现,但任何好的编译器都可能生成相同的代码。


1
投票

我这么问是因为我经常读到,最好将所有声明放在最第一行,这样对性能会更好。

我可以向你保证,这纯粹是无稽之谈。发表这样的言论的人根本不知道 C 代码是如何翻译成机器代码的。

如果您的 3 个示例中的任何一个给出了不同的机器代码,我会感到非常惊讶。


但是存在一种特殊情况:如果变量被声明为“全局”或静态,那么它们将具有静态存储持续时间。然后它们将在调用 main() 之前初始化。所有未由程序员显式初始化的全局变量/静态变量都设置为零。因此,在这种情况下,您的示例 1) 会更慢:

int x; /* global variable, no explicit init so it will get set to 
          zero before main() is called */
...
x = 4; // variable gets set a second time, elsewhere, in "runtime"

int x = 4; // global variable, gets initialized before main() is called

但这两者之间的性能差异可能只是一条 CPU 指令,因此在 99.9% 的应用程序中这并不重要。


1
投票

如果没有任何

// code
块接触
x
y
,那么您极不可能在这些选项之间遇到明显的性能差异。

如果您想确定使用编译器在硬件架构上发生了什么,您可以随时对代码进行基准测试和/或检查生成的程序集。


1
投票

1) 会有 -- 在调试中。编译器应该在发布时照顾你。

2)您可能会因为可读性而喜欢它。编译器可以完全“删除”一个常量值。

3)这可以产生影响。局部声明通常是最好的,但这在 C++ 中更为重要,因为实际的构造函数会做一些工作。有时,如果将大对象从循环中拉出,您可能会测量差异(但您的编译器应该为您做到这一点)。

我这么问是因为我经常读到,最好将所有声明放在最第一行,这样对性能会更好。

并非如此。我认为这个想法只是来自过去的语言限制。无论如何,“尽可能本地化”通常是最好的。当然,这可能会因编译器、硬件、实现等的不同而有所不同。

在 C 中,堆栈分配和初始化是微不足道的,您的编译器应该足够好地处理这个问题,以便在大多数情况下性能不是问题。

尝试一些现实世界的基准测试和分析。查看 asm(如 Aix 所说)也有帮助。

如果您没有编写汇编,也没有进行日常分析,并且这完全是 C 语言,那么不值得改变您的编写方式。


1
投票

我问这个问题是因为我经常读到最好将所有声明放在最第一行,这样对性能会更好。喜欢:

func(){
    int x,y,z,w;
    long bla,ble;
    MYTYPE weeee;
    // more declarations..
    //code..
}

不,这样做的唯一原因是在早期的 C 中,你必须将所有声明放在函数中的代码之前。

该规则在上世纪末发生了变化。


0
投票

没有普遍可预测的性能差异。


0
投票

如果编译器真的很笨,那么第二种形式是最好的。否则,它会优化其他形式。


0
投票

在C中,我认为这不会有任何区别。 在 C++ 中(不是我知道的问题),根据是否调用构造函数以及是否在循环内声明临时对象,以及调用它们的次数,您会得到很大的差异。

在 C99 中,我不确定后期声明是否在进入函数时分配堆栈空间,或者在进入块时分配堆栈空间。 这会对优化器应该处理的类似(尽管很小)的性能影响产生影响。 根据 Aix 的回答,一个好的方法是查看汇编器,看看幕后发生了什么,

© www.soinside.com 2019 - 2024. All rights reserved.