使用const参数将参数传递给函数:它更快吗?

时间:2012-09-06 00:51:08

标签: c const function-parameter

考虑一下,例如:

int sum(int a, int b)
{
    return a + b;
}

VS

int sum(const int a, const int b)
{
    return a + b;
}

第二种方法通常更快吗?

C中的函数参数被复制并发送到函数,因此函数内部的更改不会影响原始值。我的理由是,在上面的第二个sum中,编译器确定ab未在函数内部进行修改,因此它可以只传递原始值而不先复制它们。这就是为什么我认为第二个sum比第一个sum更快。但我真的不知道。在上面sum的特定简单示例中,差异(如果有的话)应该是最小的。

修改const示例仅用于说明我的观点。我不希望在这个特定的例子中应该有很大的差异。但我想知道在更复杂的情况下,编译器是否可以利用函数参数中的const修饰符来使函数更快。我怀疑编译器总能确定一个参数是否在一个函数内被改变(因此我的第二个问题在下面);因此我希望当它找到一个const修饰符时,它会做出与没有const修饰符时不同的东西。

问题:一般来说,一个函数在参数为{{1}}时比在它们不是时更快?

问题2:通常,C编译器(理论上)是否总能确定函数内是否更改了函数参数?

4 个答案:

答案 0 :(得分:15)

简答:否

答案很长,不,有证据。

在我使用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;
}

输出

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

因此,正如您所看到的,两者之间存在 无差异 。将参数传递为const只是调用者的一个提示,参数不会被更改,并且在如上所述的简单场景中,不会导致编译任何不同的汇编。

答案 1 :(得分:9)

答案可能取决于您的编译器,优化级别以及编译器是否决定内联函数。如果您对这些事情感到好奇,只需查看编译器生成的实际汇编并查找即可。

答案 2 :(得分:0)

没有。两者都应该是相同的速度。 因为你的原因,假设它将原始值传递给sum函数,sum函数中的一些代码如何修改原始值,例如,另一个线程。

通常,const对参数的性能没有影响。如果const是局部/全局变量,它会影响性能,因为某些计算可以移动到编译时,就像它是const一样。

答案 3 :(得分:0)

虽然参加派对的时间较晚,但编译器可以将定义为const的变量放在只读内存段/块中,这样如果尝试通过某些指针tomfoolery写入该地址,则会写入内存会在运行时触发异常。

- Jamey