Keep a global variable or recreate a local variable in c? - c

I've been programming with Java for Android quite some while now. Since performance is very important for the stuff I am working on I end up just spamming global variables. I guess everyone will come rushing in now and tell me this is the worst style ever, but lets keep it simple. For Android, local variables means garbage collection and garbage collection is something that kills performance.
Lately I have started using the NDK. Now I feel the urge to actually take all the local variables and change them to global variables. I am wondering though if this makes any sense in c code. Obviously it is no good style, but if it is needed for speed I'll sacrifice the style gladly.
I've looked through older threads about local vs global, but I haven't been able to find anything about speed. So my question is, if I am calling a function very often is it relevant for the speed that local variables are created and die after the function is done? Or doesn't it matter at all and I can happily keep on using the local variables.
I would test it myself, but for some reason the performance of my app goes up and down like a roller coaster and I doubt I'll be able to really make any sense of the data. I hope someone can help me out before I rewrite my whole code for nothing :)

For Android, local variables means garbage collection...
This is an incorrect statement. Local variables are allocated on the stack - not dynamically allocated on the heap.Check out this article on what gets allocated where in Java
As a rule, items allocated on the stack do not require garbage collection/freeing and "die" immediately after the execution leaves its current scope. Stack allocation/deallocation is significantly faster than heap allocation and garbage collection.
Try to avoid global variables for both style and performance reasons. Stack-allocated local variables will perform much faster.

In C, the performance difference depends on the hardware. Loading a global on a RISC processor is more instructions (because you have to load both halves of the address in separate instructions, versus an add to the stack pointer), and then you need to contend with cache issues. For the most part, you can count on your local variables being in the cache. Using globals will thrash the cache a bit and some functions may be very adversely affected.
If you have substantial performance variability while running your app, it is quite likely that your assertion about the performance impact of local variables is immaterial.
The "cost" of creating a local variable in C is zero; it's just bumping a register (the stack pointer) to make space for the local. Then you initialize that variable via whatever means are appropriate. You should be able to know if that is expensive or not by casual inspection. When the function exits, the stack pointer is returned to its previous value, regardless of how many local variables you have.
If your definition of "local variables" is heap allocated objects, though, you will suffer from the cost of memory allocation. Memory allocation is very slow in my opinion, so whatever you can do to get away from malloc/free (and 'new' in Java), the better off you'll be. (I make games, and we tend to use dlmalloc but even that is too slow for regular usage; 400ns per call adds up quick.)

On the MIPS- and ARM-based CPUs found in most Android phones, there is no reason whatsoever to move local variables to global space "for performance." Locals are stored on the stack and a stack allocation is a single op; moreover the entire stack is cleaned up at once on calling ret. Moving them to global space will just make your logic into a snarled mess of indecipherable state for no advantage.
The one place to worry about perf with creating objects is when you are allocating them on the heap (eg with malloc()). This is exactly where C is "more performant than" garbage-collected languages, because you can see and control exactly when these mallocs occur and when they are freed. It is not really the case that C malloc() is any faster than Java new; rather, because every allocation is transparent and explicit to you, you can do the necessary work to make sure that such slow operations happen as little as possible.

By the way, declaring a variable static within a C function will give you the behavior of a global without littering the global namespace.
But as mentioned, declaring automatic variables on the stack takes 0 time and accessing those variables is also extremely quick, so there is not much reason to avoid function local variables.
If you really need this extreme level of optimization you should look to inline all your commonly called functions to avoid the call overhead.

Related

C Does passing argument from function to function will copy it's content?

The code:
//function prototype
void efg(int x);
//mother functioon
abc()
{
int a=1;
efg(a);
}
When efg is executing, changing x is not changing a then we have a copy of a. But what if we dont want a copy to use memory efficiently?
One way is to pass the a's pointer &a.
I have som constrants:
Don't want to pass anything. Since I have about 20 variable.
Don't want it's pointer's. I want direct access to it.
Dont want to being globally static.
Reluctant to use Heap dynamic allocation since it's embedded also it forces me to use pointer's instead of direct access.
I want my sub function (efg) be able to use the mother function's variable (a in abc) .It means efg being able to access a directly. Why not? Also I want a being being freed after abc execution finishes, since in the way explained the variables are in stack they will freed after function finishes.
The exact problem is: sub_functions initiate some structures in the memory. After sub function is finihed its job (CPU returns to mother function) the memories must be staying untouched untill the mother function finishes (CPU return to main) and here the memory must being freed.
My best dreaming solution is to use extern variable declare to use mother function stack in sub routine.
Don't want to pass anything. Since I have about 20 variable.
I hope you aren't planning to pass 20 variables to a function or you need to start placing related variables together in the same struct. If you have 20 variables total, well what does that have to do with anything?
Don't want it's pointer's. I want direct access to it.
That doesn't make any sense without a rationale why you want direct access. Indirect access vs direct access is such a minor performance difference that one shouldn't even bother considering it. Manually optimize when you actually have real time constraints or bottlenecks, don't optimize just for the heck of it.
If you worry about performance, then one sensible approach is to use small functions with internal linkage that will surely be inlined by the compiler. Note however that inlining is an execution speed over program size optimization.
Dont want to being globally static.
That's kind of contradicting, I assume you mean declared with static storage class specified but declared at file scope. Using such variables may or may not be valid design depending on use-case. For single core embedded systems, there's not really anything wrong with such variables.
Reluctant to use Heap dynamic allocation since it's embedded also it forces me to use pointer's instead of direct access.
Yes heap allocation should be avoided for multiple reasons in such systems. I wrote a summary of all the problems here: Why should I not use dynamic memory allocation in embedded systems? However, avoiding indirect access is not a valid reason.
The exact problem is: sub_functions initiate some structures in the memory. After sub function is finihed its job (CPU returns to mother function) the memories must be staying untouched untill the mother function finishes (CPU return to main) and here the memory must being freed.
So that's solved by declaring the variables as local, on the stack, then pass its address to the other function. If you don't want any other part of the program to touch that memory in the meantime, then simply refrain from writing code which does that...
Summary: don't state a bunch of ultimatums out of the blue, for which you can't sensibly argue in favour for or against. It's pretty clear that you have limited experience of program design, let alone manual code optimization. So for now the best thing you can do is to write code as readable as possible, following well-known best practices (const correctness, private encapsulation etc etc). Because readable code also tends to be efficient, bug-free code. Whereas needlessly contrived and complex code tends to be slow, buggy and hard to maintain.

How to undeclare (delete) variable in C?

Like we do with macros:
#undef SOMEMACRO
Can we also undeclare or delete the variables in C, so that we can save a lot of memory?
I know about malloc() and free(), but I want to delete the variables completely so that if I use printf("%d", a); I should get error
test.c:4:14: error: ‘a’ undeclared (first use in this function)
No, but you can create small minimum scopes to achieve this since all scope local variables are destroyed when the scope is exit. Something like this:
void foo() {
// some codes
// ...
{ // create an extra minimum scope where a is needed
int a;
}
// a doesn't exist here
}
It's not a direct answer to the question, but it might bring some order and understanding on why this question has no proper answer and why "deleting" variables is impossible in C.
Point #1 What are variables?
Variables are a way for a programmer to assign a name to a memory space. This is important, because this means that a variable doesn't have to occupy any actual space! As long as the compiler has a way to keep track of the memory in question, a defined variable could be translated in many ways to occupy no space at all.
Consider: const int i = 10; A compiler could easily choose to substitute all instances of i into an immediate value. i would occupy 0 data memory in this case (depending on architecture it could increase code size). Alternatively, the compiler could store the value in a register and again, no stack nor heap space will be used. There's no point in "undefining" a label that exists mostly in the code and not necessarily in runtime.
Point #2 Where are variables stored?
After point #1 you already understand that this is not an easy question to answer as the compiler could do anything it wants without breaking your logic, but generally speaking, variables are stored on the stack. How the stack works is quite important for your question.
When a function is being called the machine takes the current location of the CPU's instruction pointer and the current stack pointer and pushes them into the stack, replacing the stack pointer to the next location on stack. It then jumps into the code of the function being called.
That function knows how many variables it has and how much space they need, so it moves the frame pointer to capture a frame that could occupy all the function's variables and then just uses stack. To simplify things, the function captures enough space for all it's variables right from the start and each variable has a well defined offset from the beginning of the function's stack frame*. The variables are also stored one after the other.
While you could manipulate the frame pointer after this action, it'll be too costly and mostly pointless - The running code only uses the last stack frame and could occupy all remaining stack if needed (stack is allocated at thread start) so "releasing" variables gives little benefit. Releasing a variable from the middle of the stack frame would require a defrag operation which would be very CPU costly and pointless to recover few bytes of memory.
Point #3: Let the compiler do its job
The last issue here is the simple fact that a compiler could do a much better job at optimizing your program than you probably could. Given the need, the compiler could detect variable scopes and overlap memory which can't be accessed simultaneously to reduce the programs memory consumption (-O3 compile flag).
There's no need for you to "release" variables since the compiler could do that without your knowledge anyway.
This is to complement all said before me about the variables being too small to matter and the fact that there's no mechanism to achieve what you asked.
* Languages that support dynamic-sized arrays could alter the stack frame to allocate space for that array only after the size of the array was calculated.
There is no way to do that in C nor in the vast majority of programming languages, certainly in all programming languages that I know.
And you would not save "a lot of memory". The amount of memory you would save if you did such a thing would be minuscule. Tiny. Not worth talking about.
The mechanism that would facilitate the purging of variables in such a way would probably occupy more memory than the variables you would purge.
The invocation of the code that would reclaim the code of individual variables would also occupy more space than the variables themselves.
So if there was a magic method purge() that purges variables, not only the implementation of purge() would be larger than any amount of memory you would ever hope to reclaim by purging variables in your program, but also, in int a; purge(a); the call to purge() would occupy more space than a itself.
That's because the variables that you are talking about are very small. The printf("%d", a); example that you provided shows that you are thinking of somehow reclaiming the memory occupied by individual int variables. Even if there was a way to do that, you would be saving something of the order of 4 bytes. The total amount of memory occupied by such variables is extremely small, because it is a direct function of how many variables you, as a programmer, declare by hand-typing their declarations. It would take years of typing on a keyboard doing nothing but mindlessly declaring variables before you would declare a number of int variables occupying an amount of memory worth speaking of.
Well, you can use blocks ({ }) and defining a variable as late as possible to limit the scope where it exists.
But unless the variable's address is taken, doing so has no influence on the generated code at all, as the compiler's determination of the scope where it has to keep the variable's value is not significantly impacted.
If the variable's address is taken, failure of escape-analysis, mostly due to inlining-barriers like separate compilation or allowing semantic interpositioning, can make the compiler assume it has to keep it alive till later in the block than strictly neccessary. That's rarely significant (don't worry about a handful of ints, and most often a few lines of code longer keeping it alive are insignificant), but best to keep it in mind for the rare case where it might matter.
If you are that concerned about the tiny amount of memory that is on the stack, then you're probably going to be interested in understanding the specifics of your compiler as well. You'll need to find out what it does when it compiles. The actual shape of the stack-frame is not specified by the C language. It is left to the compiler to figure out. To take an example from the currently accepted answer:
void foo() {
// some codes
// ...
{ // create an extra minimum scope where a is needed
int a;
}
// a doesn't exist here
}
This may or may not affect the memory usage of the function. If you were to do this in a mainstream compiler like gcc or Visual Studio, you would find that they optimize for speed rather than stack size, so they pre-allocate all of the stack space they need at the start of the function. They will do analysis to figure out the minimum pre-allocation needed, using your scoping and variable-usage analysis, but those algorithms literally wont' be affected by extra scoping. They're already smarter than that.
Other compilers, especially those for embedded platforms, may allocate the stack frame differently. On these platforms, such scoping may be the trick you needed. How do you tell the difference? The only options are:
Read the documentation
Try it, and see what works
Also, make sure you understand the exact nature of your problem. I worked on a particular embedded project which eschewed the stack for everything except return values and a few ints. When I pressed the senior developers about this silliness, they explained that on this particular application, stack space was at more of a premium than space for globally allocated variables. They had a process they had to go through to prove that the system would operate as intended, and this process was much easier for them if they allocated everything up front and avoided recursion. I guarantee you would never arrive at such a convoluted solution unless you first knew the exact nature of what you were solving.
As another solution you could look at, you could always build your own stack frames. Make a union of structs, where each struct contains the variables for one stack frame. Then keep track of them yourself. You could also look at functions like alloca, which can allow for growing the stack frame during the function call, if your compiler supports it.
Would a union of structs work? Try it. The answer is compiler dependent. If all variables are stored in memory on your particular device, then this approach will likely minimize stack usage. However, it could also substantially confuse register coloring algorithms, and result in an increase in stack usage! Try and see how it goes for you!

How is conditional initialization handled and is it a good practice?

I am trying to decide between several possible practices. Say, my function has a number of if() blocks, that work on data, that is unique to them.
Should I declare and initialize the local (for the block) data inside the block? Does this have runtime performance cost (due to runtime allocation in the stack)?
Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?
Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?
Or am I ovelooking another, cleaner, option? Is the question even answerable in it's current, general form?
Should I declare and initialize the local (for the block) data inside the block?
Absolutely: this tends to make programs more readable.
Does this have runtime performance cost (due to runtime allocation in the stack)?
No: all allocations are done upfront - the space on the stack is reserved for variables in all branches upon entering a function, not when the branch is entered. Moreover, this could even save you some space, because the space allocated for variables in non-overlapping branches can be reused by the compiler.
Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?
No, this is not faster, and could be slightly more wasteful.
Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?
That would probably have a negative impact on readability of your program.
It's a good practice to keep the scope of the variable as small as possible.
If you declare all the variable one time at the beginning, and you don't use
them often in your program. It's no use, it takes more memory.
Also, another advantages of keeping the scope small is that you can reuse
the same names again. (you don't have to invent new names each time you
do something trivial).
Out of the options you are stating, declare and initialize the local (for the block) data inside the block is what will serve your purpose. Forget the rest of the things.
For completeness; another, usually less important consideration is stack padding control / packing, which is intuitively more difficult if you don't declare everything upfront.
See this for more information, although let me emphasize the following paragraph before anyone does anything crazy:
Usually, for the small number of scalar variables in your C programs,
bumming out the few bytes you can get by changing the order of
declaration won’t save you enough to be significant. The technique
becomes more interesting when applied to nonscalar variables -
especially structs.
Now the answer concerning performance.
Should I declare and initialize the local (for the block) data inside the block? Does this have runtime performance cost (due to runtime allocation in the stack)?
Allocation of local variables is practically free. In most cases, it will really be free, because the update of the stack pointer is performed in the same instruction that writes the value to the stack. Deallocation is either free as well (when something is popped off the stack), or done once at the return (when a stack frame had been created).
Or should I declare and/or initialize all variables at function entry, so that is is done in one, possibly faster, operation block?
While allocation is virtually free, running constructors/destructors is not. While this does not apply to variables of primitive types, it applies to virtually all user defined types, including smart pointers and the like. If you declare a smart pointer at the beginning of the function, but only use it half of the time, you construct, and subsequently destruct the smart pointer twice as much as needed.
Also, if you declare a variable where you have the information to initialize it to your needs, you can construct it directly to the state you want it to have instead of first default constructing it only to change it's value afterwards (using the assignment operator in many cases). So, from a performance perspective, you should always declare variables late and only in the blocks that need them.
Or should I seperate the if() blocks in different functions, even though they are only a couple of lines long and used only one in the program?
No, this is completely contraproductive from a performance perspective. Each function call has an overhead, I think it's between 10 and 20 cycles most of the time. You can do quite a bit of calculation in that time.

C variable allocation time and space

If i have a test.c file with the following
#include ...
int global = 0;
int main() {
int local1 = 0;
while(1) {
int local2 = 0;
// Do some operation with one of them
}
return 0;
}
So if I had to use one of this variables in the while loop, which one would be preferred?
Maybe I'm being a little vague here, but I want to know if the difference in time/space allocation is actually relevant.
If you are wondering whether declaring a variable inside a for loop causes it to be created/destroyed at every iteration, there is nothing really to worry about. These variables are not dynamically allocated at runtime, nothing is being malloced here - just some memory is being set aside for use inside the loop. So having the variable inside is just the same as having it outside the loop in terms of performance.
The real difference here is scope not performance. Whether you use a global or local variable only affects where you want this variable to be visible.
In case you're wondering about performance differences: most likely there aren't any. If there are theoretical performance differences, you'll find it hard to actually devise a test to measure them.
A decision like this should not be based on performance but semantics. Unless the semantic behavior of a global variable is required, you should always use automatic (local non-static) variables.
As others have said and surely will say, there are unlikely to be any differences in performance. If there are, the automatic variable will be faster.
The C compiler will have an easier time making optimizations on the variables declared local to the function. The global variable would require an optimizer to perform "Inter-Procedural Data Flow Analysis", which isn't that commonly done.
As an example of the difference, consider that all your declarations initialize the variable to zero. However, in the case of the global variable, the compiler cannot use that information unless it verifies that no flow of control in your program can change the global prior to using it in your example function. In the case of the locally declared ("automatic") variables, there is no way the initial value can be changed by another function (in particular, the compiler verifies that their address is never passed to a sub-function) and the compiler can perform "killed definitions" and "value liveness" analysis to determine whether the zero value can be assumed in some code paths.
Of the two local variables, as a guideline, the optimizer will always have an easier time optimizing access to the variable with the smaller (more limited) scope.
Having stated the above, I would suggest that other answers concerning a bias toward semantics over optimizer-meta-optimization is correct. Use the variable which causes the code to read best, and you will be rewarded with more time returned to you than assisting the def-use optimization calculation.
In general, avoid using a global variable, or any variable which can be accessed more broadly than absolutely necessary. Limited scoping of variables helps prevent bugs from being introduced during later program maintenance.
There are three broad classes of variables: static (global), stack (auto), and register.
Register variables are stored in CPU registers. Registers are very fast word-sized memories, which are integrated in the CPU pipeline. They are free to access, but there are a very limited number of them (typically between 8 and 32 depending on your processor and what operations you're doing).
Stack variables are stored in an area of RAM called the stack. The stack is almost always going to be in the cache, so stack variables typically take 1-4 cycles to access.
Generally, local variables can be either in registers or on the stack. It doesn't matter whether they are allocated at the top of a function or in a loop; they will only be allocated once per function call, and allocation is basically free. The compiler will put variables in registers if at all possible, but if you have more active variables than registers, they won't all fit. Also, if you take the address of a variable, it must be stored on the stack since registers don't have addresses.
Global and static variables are a different beast. Since they are not usually accessed frequently, they may not be in cache, so it could take hundreds of cycles to access them. Also, since the compiler may not know the address of a global variable ahead of time, it may need to be looked up, which is also expensive.
As others have said, don't worry too much about this stuff. It's definitely good to know, but it shouldn't affect the way you write your programs. Write code that makes sense, and let the compiler worry about optimization. If you get into compiler development, then you can start worrying about it. :)
Edit: more details on allocation:
Register variables are allocated by the compiler, so there is no runtime cost. The code will just put a value in a register as soon as the value is produced.
Stack variables are allocated by your program at runtime. Typically, when a function is called, the first thing it will do is reserve enough stack space for all of its local variables. So there is no per-variable cost.

In C, does using static variables in a function make it faster?

My function will be called thousands of times. If i want to make it faster, will changing the local function variables to static be of any use? My logic behind this is that, because static variables are persistent between function calls, they are allocated only the first time, and thus, every subsequent call will not allocate memory for them and will become faster, because the memory allocation step is not done.
Also, if the above is true, then would using global variables instead of parameters be faster to pass information to the function every time it is called? i think space for parameters is also allocated on every function call, to allow for recursion (that's why recursion uses up more memory), but since my function is not recursive, and if my reasoning is correct, then taking off parameters will in theory make it faster.
I know these things I want to do are horrible programming habits, but please, tell me if it is wise. I am going to try it anyway but please give me your opinion.
The overhead of local variables is zero. Each time you call a function, you are already setting up the stack for the parameters, return values, etc. Adding local variables means that you're adding a slightly bigger number to the stack pointer (a number which is computed at compile time).
Also, local variables are probably faster due to cache locality.
If you are only calling your function "thousands" of times (not millions or billions), then you should be looking at your algorithm for optimization opportunities after you have run a profiler.
Re: cache locality (read more here):
Frequently accessed global variables probably have temporal locality. They also may be copied to a register during function execution, but will be written back into memory (cache) after a function returns (otherwise they wouldn't be accessible to anything else; registers don't have addresses).
Local variables will generally have both temporal and spatial locality (they get that by virtue of being created on the stack). Additionally, they may be "allocated" directly to registers and never be written to memory.
The best way to find out is to actually run a profiler. This can be as simple as executing several timed tests using both methods and then averaging out the results and comparing, or you may consider a full-blown profiling tool which attaches itself to a process and graphs out memory use over time and execution speed.
Do not perform random micro code-tuning because you have a gut feeling it will be faster. Compilers all have slightly different implementations of things and what is true on one compiler on one environment may be false on another configuration.
To tackle that comment about fewer parameters: the process of "inlining" functions essentially removes the overhead related to calling a function. Chances are a small function will be automatically in-lined by the compiler, but you can suggest a function be inlined as well.
In a different language, C++, the new standard coming out supports perfect forwarding, and perfect move semantics with rvalue references which removes the need for temporaries in certain cases which can reduce the cost of calling a function.
I suspect you're prematurely optimizing, however, you should not be this concerned with performance until you've discovered your real bottlenecks.
Absolutly not! The only "performance" difference is when variables are initialised
int anint = 42;
vs
static int anint = 42;
In the first case the integer will be set to 42 every time the function is called in the second case ot will be set to 42 when the program is loaded.
However the difference is so trivial as to be barely noticable. Its a common misconception that storage has to be allocated for "automatic" variables on every call. This is not so C uses the already allocated space in the stack for these variables.
Static variables may actually slow you down as its some aggresive optimisations are not possible on static variables. Also as locals are in a contiguous area of the stack they are easier to cache efficiently.
There is no one answer to this. It will vary with the CPU, the compiler, the compiler flags, the number of local variables you have, what the CPU's been doing before you call the function, and quite possibly the phase of the moon.
Consider two extremes; if you have only one or a few local variables, it/they might easily be stored in registers rather than be allocated memory locations at all. If register "pressure" is sufficiently low that this may happen without executing any instructions at all.
At the opposite extreme there are a few machines (e.g., IBM mainframes) that don't have stacks at all. In this case, what we'd normally think of as stack frames are actually allocated as a linked list on the heap. As you'd probably guess, this can be quite slow.
When it comes to accessing the variables, the situation's somewhat similar -- access to a machine register is pretty well guaranteed to be faster than anything allocated in memory can possible hope for. OTOH, it's possible for access to variables on the stack to be pretty slow -- it normally requires something like an indexed indirect access, which (especially with older CPUs) tends to be fairly slow. OTOH, access to a global (which a static is, even though its name isn't globally visible) typically requires forming an absolute address, which some CPUs penalize to some degree as well.
Bottom line: even the advice to profile your code may be misplaced -- the difference may easily be so tiny that even a profiler won't detect it dependably, and the only way to be sure is to examine the assembly language that's produced (and spend a few years learning assembly language well enough to know say anything when you do look at it). The other side of this is that when you're dealing with a difference you can't even measure dependably, the chances that it'll have a material effect on the speed of real code is so remote that it's probably not worth the trouble.
It looks like the static vs non-static has been completely covered but on the topic of global variables. Often these will slow down a programs execution rather than speed it up.
The reason is that tightly scoped variables make it easy for the compiler to heavily optimise, if the compiler has to look all over your application for instances of where a global might be used then its optimising won't be as good.
This is compounded when you introduce pointers, say you have the following code:
int myFunction()
{
SomeStruct *A, *B;
FillOutSomeStruct(B);
memcpy(A, B, sizeof(A);
return A.result;
}
the compiler knows that the pointer A and B can never overlap and so it can optimise the copy. If A and B are global then they could possibly point to overlapping or identical memory, this means the compiler must 'play it safe' which is slower. The problem is generally called 'pointer aliasing' and can occur in lots of situations not just memory copies.
http://en.wikipedia.org/wiki/Pointer_alias
Using static variables may make a function a tiny bit faster. However, this will cause problems if you ever want to make your program multi-threaded. Since static variables are shared between function invocations, invoking the function simultaneously in different threads will result in undefined behaviour. Multi-threading is the type of thing you may want to do in the future to really speed up your code.
Most of the things you mentioned are referred to as micro-optimizations. Generally, worrying about these kind of things is a bad idea. It makes your code harder to read, and harder to maintain. It's also highly likely to introduce bugs. You'll likely get more bang for your buck doing optimizations at a higher level.
As M2tM suggests, running a profiler is also a good idea. Check out gprof for one which is quite easy to use.
You can always time your application to truly determine what is fastest. Here is what I understand: (all of this depends on the architecture of your processor, btw)
C functions create a stack frame, which is where passed parameters are put, and local variables are put, as well as the return pointer back to where the caller called the function. There is no memory management allocation here. It usually a simple pointer movement and thats it. Accessing data off the stack is also pretty quick. Penalties usually come into play when you're dealing with pointers.
As for global or static variables, they're the same...from the standpoint that they're going to be allocated in the same region of memory. Accessing these may use a different method of access than local variables, depends on the compiler.
The major difference between your scenarios is memory footprint, not so much speed.
Using static variables can actually make your code significantly slower. Static variables must exist in a 'data' region of memory. In order to use that variable, the function must execute a load instruction to read from main memory, or a store instruction to write to it. If that region is not in the cache, you lose many cycles. A local variable that lives on the stack will most surely have an address that is in the cache, and might even be in a cpu register, never appearing in memory at all.
I agree with the others comments about profiling to find out stuff like that, but generally speaking, function static variables should be slower. If you want them, what you are really after is a global. Function statics insert code/data to check if the thing has been initialized already that gets run every time your function is called.
Profiling may not see the difference, disassembling and knowing what to look for might.
I suspect you are only going to get a variation as much as a few clock cycles per loop (on average depending on the compiler, etc). Sometimes the change will be dramatic improvement or dramatically slower, and that wont necessarily be because the variables home has moved to/from the stack. Lets say you save four clock cycles per function call for 10000 calls on a 2ghz processor. Very rough calculation: 20 microseconds saved. Is 20 microseconds a lot or a little compared to your current execution time?
You will likely get more a performance improvement by making all of your char and short variables into ints, among other things. Micro-optimization is a good thing to know but takes lots of time experimenting, disassembling, timing the execution of your code, understanding that fewer instructions does not necessarily mean faster for example.
Take your specific program, disassemble both the function in question and the code that calls it. With and without the static. If you gain only one or two instructions and this is the only optimization you are going to do, it is probably not worth it. You may not be able to see the difference while profiling. Changes in where the cache lines hit could show up in profiling before changes in the code for example.

Resources