views:

79

answers:

4

Hello,

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 :)

+4  A: 

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.)

dash-tom-bang
Thank you for the quick reply! I guess I still have a lot to learn. But I am glad I can keep on using local variables in c. It is a pain in java. And to answer your comment, I guess I picked the wrong words, but what I have noticed if I call a function 20 times a second and in the function I create for example a local int, this will be garbage collected after the function is done and that just costs a lot of time. That's why I ended up with many global variables there.
Pandoro
Local integers or other primitive data types should not require any fancy garbage collection even in Java.
dash-tom-bang
+5  A: 

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.

advait
Good to know! Since I always tried, all global vs all local variables I got a better performance on the all global approach. Mainly because I do use a lot of objects and arrays. But if I get you right I could just leave all the primitive data types local since they won't go to the heap anyways?
Pandoro
+1 It's sad that a lot of Java programmers don't know the difference between Stack and Heap allocation. But I have to admit, until I've learned C I also didn't bother :-).
Helper Method
@Pandoro See http://cslibrary.stanford.edu/102/PointersAndMemory.pdf. This was a real eye opener too me.
Helper Method
+1  A: 

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.

Crashworks
Agreed. In fact, `malloc` is usually a lot slower than `new`, and a GC sweep is often faster than the corresponding number of calls to `free`. But expert C coders are used to being careful enough with memory allocation to more than make up the difference (or to write their own specialized memory handling routines that are even faster for their use case).
Rex Kerr
A: 

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.

Reuben Vogel