Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is const int faster than const int&?

Tags:

c++

visual-c++

I noticed this accidentally one day, and now decided to test it extensively.

So, when I call a function:

#define Type int
#define Prm const Type &
Type testfunc1(Prm v1, Prm v2, Prm v3, Prm v4, Prm v5, Prm v6, Prm v7, Prm v8, Prm v9, Prm v10){
    return (v1|v2|v3|v4|v5|v6|v7|v8|v9|v10);
}

100 million times:

        for(Type y = 0; y < 10000; y++){
            for(Type x = 0; x < 10000; x++){
                out |= testfunc1(x,y,x,x,y,y,x,y,x,y);
            }
        }

With types int, const int and const int &, i notice that const int is faster than const int &. (Note: im using the return value to ensure the function wont get optimized off).

Why is it so? I always thought adding & would actually make it faster, but the tests say the opposite. I know for bigger datatypes it would probably be different outcome, I didnt test those though since I'm quite sure about the results.

My tests:

const int: 7.95s
const int &: 10.2s

Edit: I think it is indeed because of my architecture; I tested with Sint64 type and the results were:

const Sint64: 17.5s
const Sint64 &: 16.2s

Edit2: Or is it? Tested with double type (which is 64bit?), and results make me puzzled:

const double: 11.28s
const double &: 12.34s

Edit3: updated the loop code to match my newest tests with 64bit types.

like image 294
Rookie Avatar asked Dec 04 '22 04:12

Rookie


2 Answers

By putting a & into the argument, you are adding more code to the program. Without the &, the sequence is:

 push values
 call Function
 pop values <- usually an update to stack pointer

and in Function:

 return sp[arg1] | sp[arg2] | etc <- value read direct from stack.

Adding the '&' does this:

 push address of value1
 push address of value2
 etc
 call Function
 pop values <- usually an update to stack pointer

and in Function:

 return_value = 0;
 address = sp[arg1]
 or return_value, [address]
 address = sp[arg2]
 or return_value, [address]
 etc
 return return_value

So, as you can see, the & adds a lot. So why use it? If you have a very large object, passing a pointer is more optimal than copying the object to the stack.

like image 163
Skizz Avatar answered Dec 21 '22 20:12

Skizz


This result is heavily system-dependent. It indicates that on your particular system copying a value of a reference (which is most likely implemented as a pointer) has higher cost than copying a value of an integer. The most probable reason for that difference is that your integer requires 32-bits to represent, and your pointer/reference representation requires 64-bits. EDIT This is not to mention the cost of accessing your integers: getting their values would require an additional indirection. Since you are passing only two items, use of caching hides that additional cost to a large extent, but the cost is there.

You are absolutely right about larger types, though: passing a reference to, say, a large struct or a vector<...> still requires only 64 bit (or whatever that size is on your system), regardless of how many items your structure has, or how many items your vector<...> holds. The larger the structure, the higher the costs to pass it by value, and therefore the savings that you realize by making it a reference.

like image 24
Sergey Kalinichenko Avatar answered Dec 21 '22 18:12

Sergey Kalinichenko