151 c++ loops variable-declaration
我只是想知道如果你做了这样的事情会有任何速度或效率的损失:
int i = 0;
while(i < 100)
{
int var = 4;
i++;
}
Run Code Online (Sandbox Code Playgroud)
宣告int var一百次.在我看来会有,但我不确定.这样做会更实际/更快:
int i = 0;
int var;
while(i < 100)
{
var = 4;
i++;
}
Run Code Online (Sandbox Code Playgroud)
或者它们是相同的,速度和效率方面的?
laa*_*lto 190
局部变量的堆栈空间通常在函数范围内分配.因此,循环内部不会发生堆栈指针调整,只需指定4即可var.因此,这两个片段具有相同的开销.
Ada*_*eld 98
对于原始类型和POD类型,它没有任何区别.编译器将在函数开头为变量分配堆栈空间,并在函数返回时解除分配.
对于具有非平凡构造函数的非POD类类型,它会产生影响 - 在这种情况下,将变量放在循环之外只会调用构造函数和析构函数一次,并且每次迭代都会调用赋值运算符,而将其置于loop将为循环的每次迭代调用构造函数和析构函数.根据类的构造函数,析构函数和赋值运算符的作用,这可能是也可能不是.
Ale*_*own 67
它们都是相同的,通过查看编译器的功能(即使没有将优化设置为高),您可以通过以下方式找到它们:
看看编译器(gcc 4.0)对你的简单例子的作用:
1.C:
main(){ int var; while(int i < 100) { var = 4; } }
Run Code Online (Sandbox Code Playgroud)
gcc -S 1.c.
1.S:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
Run Code Online (Sandbox Code Playgroud)
2.C
main() { while(int i < 100) { int var = 4; } }
Run Code Online (Sandbox Code Playgroud)
gcc -S 2.c.
2.S:
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -16(%ebp)
jmp L2
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
leave
ret
Run Code Online (Sandbox Code Playgroud)
从这些中,您可以看到两件事:首先,两者中的代码是相同的.
其次,var的存储在循环外部分配:
subl $24, %esp
Run Code Online (Sandbox Code Playgroud)
最后,循环中唯一的东西是赋值和条件检查:
L3:
movl $4, -12(%ebp)
L2:
cmpl $99, -16(%ebp)
jle L3
Run Code Online (Sandbox Code Playgroud)
如果不完全删除循环,那么效率就会高得多.
Jos*_*hua 12
这些天最好在循环中声明它,除非它是一个常量,因为编译器将能够更好地优化代码(减少变量范围).
编辑:这个答案现在已经过时了.随着后经典编译器的兴起,编译器无法弄清楚的情况越来越少.我仍然可以构建它们,但大多数人会将构造归类为坏代码.
And*_*are 10
大多数现代编译器都会为您优化.话虽如此,我会使用你的第一个例子,因为我发现它更具可读性.
对于内置类型,两种样式之间可能没有区别(可能直到生成的代码).
但是,如果变量是具有非平凡构造函数/析构函数的类,那么运行时成本可能会有很大差异.我通常将变量范围限定在循环内部(以保持范围尽可能小),但如果事实证明具有性能影响,我会将类变量移到循环范围之外.但是,这样做需要一些额外的分析,因为ode路径的语义可能会发生变化,因此只有在sematics允许的情况下才能这样做.
RAII类可能需要此行为.例如,可能需要在每次循环迭代时创建和销毁管理文件访问生存期的类,以正确管理文件访问.
假设你有一个LockMgr类在构造时获取一个关键部分,并在销毁时释放它:
while (i< 100) {
LockMgr lock( myCriticalSection); // acquires a critical section at start of
// each loop iteration
// do stuff...
} // critical section is released at end of each loop iteration
Run Code Online (Sandbox Code Playgroud)
与以下内容完全不同:
LockMgr lock( myCriticalSection);
while (i< 100) {
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50161 次 |
| 最近记录: |