Reputation: 2006
I have a function that needs quite some internal temporary storage for its computations (some matrix operations) and I know that this function will be called frequently (say every millisecond throughout the runtime of the program). My gut feeling tells me that it's better to declare those temporary variables static, so there's not so much administrative effort for creating them again and again with each call of the function. I have to initialized them anyway every time the function is called, so keeping them alive is not needed for functional purposes. I am aware that making them static breaks thread-safety, but this is not an issue here.
As knowledge is usually better than any gut feeling, I'd like to know what the "correct" way of handling this case is.
void frequentlyCalledFunction(void)
{
double matrix1[10][10];
double matrix2[10][10];
/* do something with the matrices ... */
}
or
void frequentlyCalledFunction(void)
{
static double matrix1[10][10];
static double matrix2[10][10];
/* do something with the matrices ... */
}
Upvotes: 8
Views: 2140
Reputation: 11821
On SPARC especially in 64 bits mode, the static case is slower. The access to a global variable (which the static is, it's only the name that is limited to the scope of the function) needs 5 instructions using 3 register, in your case 10 instructions only to get the address of the arrays. The non static version, as was already pointed out, has no overhead, as the frame is built up in anycase, if the stack pointer grows 16 bytes or 200 makes no difference. But be careful if you init your array, this can yield a hidden memset that can be costly.
void frequentlyCalledFunction(void)
{
double matrix1[10][10]={0.0};
double matrix2[10][10]={0.0};
/* do something with the matrices ... */
}
will probably make 1 or 2 memcpy or memset calls to initialise the arrays.
Upvotes: 1
Reputation: 169553
Reserving space for variables with automatic storage duration means just decreasing the stack pointer, so as long as these aren't the only local variables, there's no overhead.
What might hurt performance is that stack-allocated variables have to be addressed relative to stack or base pointer, so using static
might slightly improve performance.
As always, benchmark the code to make sure.
Upvotes: 0
Reputation: 6208
Allocating stack variables aren't like allocating heap variables all that happens is the stack pointer is moved down far enough to allocate all the memory needed by the function. There is no overhead in allocating one or one hundred variables in a stack frame. The stack pointer is already going to be moved when the function is called even if there are zero variables (to record where to return to etc.)
Upvotes: 2
Reputation: 1500055
I would definitely write it the simplest and most readable way first. Once per millisecond sounds like a very rarely run function to be micro-optimising.
Once you've got it working, benchmark it. Decide if performance is good enough. If it's not, optimise and benchmark again. Don't bend clean code out of shape without very solid numbers to back up your decision.
Upvotes: 10
Reputation: 10142
As usual, you should be profiling first. Local variables probably only cause the stack pointer to be decremented a bit more which should not have any performance penalty.
Upvotes: 5
Reputation: 300529
You are attempting a micro-optimisation without benchmarking, which is generally deemed to be a bad thing. You should always benchmark. Otherwise , how will you know for sure that any attempt at optimisation worked?
It is unlikely you will gain anything from doing so, and code readability and maintainabilty should come first.
Upvotes: 2
Reputation: 239011
The only way to know is to try it and test it. It is unlikely to make much difference, though.
Upvotes: 1
Reputation: 281405
There's no difference. There's no code needed to "create" an uninitialised array.
In the case of a static array, the memory is reserved and available all the time. In the case of an automatic array, it's on the stack, and all that's required to "create" it is to move the stack pointer, which is going to happen anyway on entry to the function.
(And one day you'll try to use that function in a multithreaded program, and the static version will suffer occasional intermittent failures that drive you to drink and drugs. It's just not worth the risk.)
Upvotes: 16