C 在循环内部或外部声明变量,会有很大的区别吗?
比如说C 在循环内部或外部声明变量,会有很大的区别吗?,c,performance,variable-declaration,C,Performance,Variable Declaration,比如说 int i, a, c, d; // these vars will only be used in while while(bigNumber--) { i = doSomething(); // ** } 及 这对性能有很大影响吗?是的。变量i的范围在两种情况下都不同 在第一种情况下,我在一个块或函数中声明了一个变量。因此,您可以在块或函数中访问它 在第二种情况下,我在while循环中声明了一个变量。因此,您只能在while循环中访问它 这对性能有很大影响吗 否,
int i, a, c, d; // these vars will only be used in while
while(bigNumber--) {
i = doSomething();
// **
}
及
这对性能有很大影响吗?是的。变量
i
的范围在两种情况下都不同
在第一种情况下,我在一个块或函数中声明了一个变量。因此,您可以在块或函数中访问它
在第二种情况下,我在while循环中声明了一个变量。因此,您只能在while循环中访问它
这对性能有很大影响吗
否,从性能角度讲,您在哪里声明它并不重要
对于示例1:
int main()
{
int i, bigNumber;
while(bigNumber--) {
i = 0;
}
}
int main()
{
int bigNumber;
while(bigNumber--) {
int i;
i = 0;
}
}
组件:
main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret
main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret
示例2:
int main()
{
int i, bigNumber;
while(bigNumber--) {
i = 0;
}
}
int main()
{
int bigNumber;
while(bigNumber--) {
int i;
i = 0;
}
}
组件:
main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret
main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret
两者都生成相同的汇编代码。这会产生不同……当你在循环外声明变量时,你可以在循环结束后得到它的值,但如果你在循环内声明它,你就不能在循环后使用它,因为它没有定义。Q。它在性能方面会有很大的不同吗
A.根本没有性能差异。唯一的区别在于变量的范围是否在循环外部可见。和I/O操作是最有价值的事情,您必须将其视为程序中的性能瓶颈。这两种代码之间没有性能差异。此外,编译器对代码进行了一些优化,如果这两个代码运行方式相同(即编译器自动将第二个代码转换为第一个代码),这并不意外。我在汇编结果中看到的唯一区别是
movl$0,-4(%rbp)
指令的位置。理论上,如果代码使用的数据在内存中分布得更广,那么可能会对代码的性能造成影响(理论上,这会使代码的缓存不那么友好)
在实践中没有什么区别。缓存足够大,优化将使两个代码生成相同的程序集,并且很可能代码将被重新排序。下面是一个关闭和打开所有优化的简单测试用例
装配结果:
代码:
打开优化器将生成完全相同的结果:
我认为如果你这样说,它会不断地重新声明变量,因此无论你初始化什么,在变量重新声明之后,它都会丢失
while(bigNumber--) {
int i, a, b, c;
i = doSomething();
}
好吧,你可以坐在板凳上。但是如果
doSomething
是一个大的过程,它将不可见difference@Jean-Françoisfafre——没有优化,GCC已经在一个小过程中生成了完全相同的代码。对于O2,它认为两个代码段是相同的(因此需要一个来完成其他的工作)。这取决于编译器将两者转换的方式,以及计算机在运行时优化的方式,因此不可能非常坚定地回答。无论如何,它不太可能观察到任何重大差异。@StoryTeller我误读了,我认为变量在一个案例中是全局的。好啊