Let's say I have a loop which repeats millions of times. Inside of this loop I have a function call.
Inside of this function I need to operate on some temporary variable created at the very beginning. Now, which one is better:
a) Create temporary variable at the beginning of the code, initialize it at the beginning of the loop, and pass it as function parameter
b) Create just local temporary variable at the beginning of the called function?
Is this answerable question? I'd like to know which point is considered better practice, or which one is faster.
Parameters can be used as a special type of variable, but the basic difference is scope: that a variable is local (it only exists within the current method), whereas a parameter is external: it is passed in to the method from the caller.
Function parameters are always locally scoped.
A parameter is a named variable passed into a function. Parameter variables are used to import arguments into functions. Note the difference between parameters and arguments: Function parameters are the names listed in the function's definition.
An assignment statement in a function creates a local variable for the variable on the left hand side of the assignment operator. It is called local because this variable only exists inside the function and you cannot use it outside.
Let's throw up some possible definitions for some_function()
, the function you will be calling from your loop.
// Method 1
void some_function() {
int temporary;
// Use temporary
}
// Method 2
void some_function(int temporary) {
// Use temporary
}
// Method 3
void some_function(int *temporary) {
// Use *temporary
}
Method 1 is likely to be the most readable out of these options, and so it's the one I would prefer unless you have a really good reason to do something else. It is also likely to be faster than either of the others, unless your compiler is inlining the function call. If it is, then all three are likely to perform exactly the same (method 3 might still be slower if the compiler isn't able to optimize away the pointer dereferences).
If the compiler is not inlining, then method 2 is likely to be slower than method 1. This is because, in terms of stack-allocated memory, they are the same -- function arguments are going to be stored on the stack the same way locals are. The only difference between a function argument and a local in this context is that the function argument can be given a value by the caller. This step of transferring the value from the caller to the function is (theoretically) going to slow down the invocation.
Method 3 is almost certainly going to be slower, since accesses to the temporary memory will include a level of indirection. Dereferencing a pointer is not a cheap operation compared to accessing a local.
Of course, if performance is absolutely critical then you should benchmark these approaches. I suspect that method 1 will turn out to be the fastest (or at least no slower than the others) and additionally seems more readable to me.
If the variable is not needed outside the function, then it should be inside the function. This allows the compiler to do the best job of optimising the code, as well as making the code most readable and easy to use (this applies generally, "declare variables with the smallest possible scope", although for small functions, declaring a handful of variables at the top of the function each time is the best option).
From a performance perspective, passing a variable to a function is either equivalent, or worse than having a local variable. [And of course, the compiler may inline everything and you end up with exactly the same code in both cases, but that's dependent on the compiler and the code you have].
As others have mentioned, passing a pointer to a local variable will incur a "penalty" for accessing the pointer to get the value. It may not make a huge difference, but it almost certainly makes some difference. This should definitely be the last resort. [Note that if the variable is LARGE, the overhead of passing a copy to the function may still be worse than the overhead of a pointer. But if we assume it's a simple type like int
or float
, then a pointer has noticeable overhead].
Any time there is a question on performance, you DEFINITELY should benchmark YOUR code. Asking someone else on the internet may be worthwhile if there is a choice between algorithms for sorting or something like that, but if it's a case of "is it better to do this or that" in some more subtle differences, then the differences are often small and what your particular compiler does will have much more influence than "which is theoretically better".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With