Passing arguments to functions with const parameters: is it faster?

冷暖自知 提交于 2019-12-03 11:00:55

问题


Consider, for example:

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

vs.

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

Is the second approach in general faster?

Function parameters in C are copied and sent to the function, so that changes inside the function do not affect the original values. My reasoning is that in the second sum above, the compiler knows for sure that a and b are not modified inside the function, so it can just pass the original values without copying them first. That's why I think the second sum is faster than the first. But I don't really know. In the particular simple example of sum above, the differences, if any, should be minimal.

Edit: The sum example is just to illustrate my point. I don't expect that in this particular example there should be large differences. But I wonder if in more complicated situations the const modifier inside a function parameter can be exploited by the compiler to make the function faster. I doubt that the compiler can always determine whether a parameter is changed inside a function (hence my 2nd question below); hence I'd expect that when it finds a const modifier, it does something different than when there's no const modifier.

Question: In general, a function will be faster when its arguments are const, than when they are not?

Question 2: In general, can a C compiler (theoretically) always determine whether a function parameter is changed inside the function?


回答1:


Short answer: No

Long answer, no, with proof.

I ran this test, a couple of times, and saw no real time difference, on my MacBook pro compiled with clang:

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;
}

Output

add took 4875711 ticks
cadd took 4885519 ticks

These times really should be taken with a grain of salt, however, as clock isn't the most accurate of timing functions, and can be influenced by other running programs.

So, here is the compared assembly generated:

_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

So, as you can see, there is No difference between the two. Passing an argument as const is only a hint to the caller the the argument will not be changed, and in a simple scenario like the one described above, will not result in any different assembly compiled.




回答2:


The answer probably depends on your compiler, the optimization level, and whether the compiler decides to inline the function. If you are curious about these things, it is easy to just look at the actual assembly produced by your compiler and find out.




回答3:


No. both of them should be same speed. for your reason, assume it passes the original values in to sum function, how about some code out of the sum function modify the original value, for example, another thread.

In general, the const has no impact the performance at arguments. it do impact the performance if the const is a local/global variable because some calculation can be moved to compiling time as if it is a const.




回答4:


Although late to the party, a compiler could put variables defined as const in a read-only memory segment/block, so that if an attempt was made to write to the address, via some pointer tomfoolery, the write to the memory would trigger an exception at runtime.

-- Jamey



来源:https://stackoverflow.com/questions/12291607/passing-arguments-to-functions-with-const-parameters-is-it-faster

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!