(You can just read the conclusion at the end if you like)
I did a benchmark to test this, I first ran this short program about ten times:
#include <iostream>
#include <ctime>
using namespace std;
int returnMe(int me)
{
return me;
}
int main()
{
float begin = (float)clock();
for(int i = 0; i < 100000000; i++)
{
int me = returnMe(i);
}
printf("\nTime: %f\n", begin);
printf("\nTime: %f\n", (float)clock());
return 0;
}
Which basically executes the function returnMe
a hundred million times, and then tells me how long that took. Values ranged from 280 ms to 318ms. Then I ran this program:
#include <iostream>
#include <ctime>
using namespace std;
int returnMe(int me, int me87 = 0, int m8e = 0, int m5e = 0, int m34e = 0,int m1e = 0,int me234 = 0,int me332 = 0,int me43 = 0,int me34 = 0,int me3 = 0,int me2 = 0,int me1 = 0)
{
return me;
}
int main()
{
float begin = (float)clock();
for(int i = 0; i < 100000000; i++)
{
int me = returnMe(i);
}
printf("\nTime: %f\n", begin);
printf("\nTime: %f\n", (float)clock());
return 0;
}
about ten times, and values were now ranging from 584 ms to 624 ms.
Conclusion: Yes, it will make the function call slower, but by a very small amount. Creating a separate function for passing the other arguments to the object, or having a different constructor, would be a performance gain, but would it be worth the extra code?
There is another way of solving it, used by Box2D, which is basically creating a separate struct for the default arguments, and passing a pointer to an instance of it. That way, when no extra arguments need to be set, the only "garbage argument" passed that decreases your performance is one nullpointer, and that is not so bad. When you want to specify some of the default values, you create an instance of said struct at stack, fill in the the values you want, then pass its address to the function. Easy, elegant and efficient.
However: Both proposed solutions for saving the performance (an extra function and passing a struct pointer) do require additional code. If your function will be called rarely, and the extra arguments are not that many, chances are the saved performance will not make any difference at all, and if that is the case, it's not worth your time. Only optimize if it's necessary. Remember I added 12 default arguments and didn't even double the function calling time.
========
EDIT: bonus for serious testing.
So the first two tests were done with plain simple compile command g++ test.cpp -o test.exe
. As pointed out in numerous comments, that implies an optimization level of -O0. What results would we get from testing at -O3?
I repeated the tests now compiling with g++ test.cpp -o test.exe -O3
, but found that the program was now completing in under 1-2 ms. I tried to vamp up the iterations to one trillion, then one hundred trillion, same result. So I figured g++ was probably seeing I was declaring a variable I was not going to use, and therefore probably skipping the calls to returnMe
, and maybe the whole loop altogether.
To get some useful results, I added actual functionality to returnMe
, to make sure that it was not optimized away. Here are the programs used:
#include <iostream>
#include <ctime>
using namespace std;
long long signed int bar = 0;
int returnMe(int me)
{
bar -= me;
return me;
}
int main()
{
float begin = (float)clock();
for(int i = 0; i < 1000000000; i++)
{
int me = returnMe(i);
bar -= me * 2;
}
printf("\nTime: %f\n", begin);
printf("\nTime: %f\n", (float)clock());
printf("Bar: %i\n", bar);
return 0;
}
and
#include <iostream>
#include <ctime>
using namespace std;
long long signed int bar = 0;
int returnMe(int me, int me87 = 0, int m8e = 0, int m5e = 0, int m34e = 0,int m1e = 0,int me234 = 0,int me332 = 0,int me43 = 0,int me34 = 0,int me3 = 0,int me2 = 0,int me1 = 0)
{
bar -= me;
return me;
}
int main()
{
float begin = (float)clock();
for(int i = 0; i < 1000000000; i++)
{
int me = returnMe(i);
bar -= me * 2;
}
printf("\nTime: %f\n", begin);
printf("\nTime: %f\n", (float)clock());
printf("Bar: %i\n", bar);
return 0;
}
Results:
First program: from 653 to 686 ms
Second program: from 652 to 735 ms
As I expected, the second program is still slower than the first, but the difference is now less noticeable.