bec*_*cko 21 c const function-parameter
例如,考虑一下:
int sum(int a, int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
与
int sum(const int a, const int b)
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
第二种方法通常更快吗?
C中的函数参数被复制并发送到函数,因此函数内部的更改不会影响原始值.我的理由是,在sum上面的第二个中,编译器确实知道a并且b没有在函数内部进行修改,所以它只能传递原始值而不先复制它们.这就是为什么我认为第二个sum比第一个更快.但我真的不知道.在sum上面特别简单的例子中,差异(如果有的话)应该是最小的.
编辑:这个sum例子只是为了说明我的观点.我不希望在这个特定的例子中应该有很大的差异.但我想知道在更复杂的情况下const,编译器是否可以利用函数参数中的修饰符来使函数更快.我怀疑编译器总能确定一个参数是否在一个函数内被改变(因此我的第二个问题在下面); 因此我希望当它找到一个const修饰符时,它会做出与没有const修饰符时不同的东西.
问题:一般来说,一个函数在它的参数时会const比它们不是时更快?
问题2:通常,C编译器(理论上)是否总能确定函数内是否更改了函数参数?
Ric*_*III 16
简答:不
答案很长,不,有证据.
在我使用clang编译的MacBook pro上,我运行了几次这个测试,看到没有实际时间差异:
int add(int a, int b)
{
return a + b;
}
const int cadd(const int a, const int b)
{
return a + b;
}
int main (int argc, char * argv[])
{
#define ITERS 1000000000
clock_t start = clock();
int j = 0;
for (int i = 0; i < ITERS; i++)
{
j += add(i, i + 1);
}
printf("add took %li ticks\n", clock() - start);
start = clock();
j = 0;
for (int i = 0; i < ITERS; i++)
{
j += cadd(i, i + 1);
}
printf("cadd took %li ticks\n", clock() - start);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量
add took 4875711 ticks cadd took 4885519 ticks
然而,这些时间确实应该花费一些时间,因为clock它不是最精确的计时功能,并且可能受到其他正在运行的程序的影响.
那么,这是生成的比较汇编:
_add:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %esi
addl -8(%rbp), %esi
movl %esi, %eax
popq %rbp
ret
_cadd:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %esi
addl -8(%rbp), %esi
movl %esi, %eax
popq %rb
Run Code Online (Sandbox Code Playgroud)
所以,正如你所看到的,两者之间没有区别.传递参数const只是对调用者的一个提示,参数不会被改变,并且在如上所述的简单场景中,不会导致编译任何不同的汇编.
| 归档时间: |
|
| 查看次数: |
22624 次 |
| 最近记录: |