暂时没有使用过C++.我一直依靠我的Java编译器来进行优化.
什么是在C++中进行for循环的最优化方法?或者现在与现代编译器完全相同?在"旧时代",存在差异.
for (int i=1; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)
要么
int i;
for (i=1; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)
要么
int i = 1;
for ( ; i<=100; i++)
Run Code Online (Sandbox Code Playgroud)
在C中它是一样的吗?
编辑: 好的,所以压倒性的共识是使用第一种情况,并让编译器优化它,如果它想.
Jav*_*ier 12
我会说像这样的微不足道的东西可能是由编译器优化的,你不应该担心它们.第一个选项是最易读的,所以你应该使用它.
编辑:添加其他答案所说的,还有不同之处在于,如果在循环初始化程序中声明变量,它将在循环结束后停止存在.
差异在于范围.
for(int i = 1; i <= 100; ++i)
Run Code Online (Sandbox Code Playgroud)
通常是优选的,因为那时i的范围仅限于for循环.如果在for循环之前声明它,那么它在for循环结束后继续存在并且可能与其他变量冲突.如果你只是在for循环中使用它,那么就没有理由让它存在的时间长于那个.
小智 5
让我们说原始海报有一个他们真正想要优化的循环 - 每个指令都被计算在内.我们怎样才能 - 凭经验 - 弄清楚他的问题的答案?
gcc至少有一个有用的,如果不常用的开关,'-S'.它转储.c文件的汇编代码版本,可用于回答OP姿势等问题.我写了一个简单的程序:
int main( )
{
int sum = 0;
for(int i=1;i<=10;++i)
{
sum = sum + i;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
并运行:gcc -O0 -std=c99 -S main.c,创建主程序的汇编版本.这是main.s的内容(删除了一些绒毛):
movl $0, -8(%rbp)
movl $1, -4(%rbp)
jmp .L2
.L3:
movl -4(%rbp), %eax
addl %eax, -8(%rbp)
addl $1, -4(%rbp)
.L2:
cmpl $10, -4(%rbp)
jle .L3
Run Code Online (Sandbox Code Playgroud)
你不需要成为装配专家来弄清楚发生了什么.movl移动值,addl添加东西,cmpl比较和jle代表'jump if than',$是常量.它将0加载到某个东西 - 必须是'sum',1加入其他东西 - 啊,'我'!跳转到L2我们比较10,跳转到L3进行添加.再次进入L2进行比较.整齐!一个for循环.
将程序更改为:
int main( )
{
int sum = 0;
int i=1;
for( ;i<=10;++i)
{
sum = sum + i;
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
重新运行gcc和由此产生的组件将非常相似.有一些东西正在记录行号,所以它们不会相同,但程序集最终是相同的.与最后一个案例相同的结果.因此,即使没有优化,代码也差不多.
为了好玩,请使用'-O3'而不是'-O0'重新运行gcc以启用优化并查看.s文件.
main:
movl $55, %eax
ret
Run Code Online (Sandbox Code Playgroud)
gcc不仅弄清楚我们正在做一个for循环,而且还意识到它在编译时为我们循环运行了一段时间,清除了'i'和'sum'并硬编码了答案 - 55 !这很快 - 尽管有点做作.
故事的道德启示?花时间确保您的代码干净且设计精良.可读性和可维护性代码.生活在山露和cheetos上的人比我们更聪明,并为我们处理了大部分这些简单的优化问题.玩得开心!
| 归档时间: |
|
| 查看次数: |
8909 次 |
| 最近记录: |