3

I saw this question asking about whether globals are bad.

As I thought about the ramifications of it, the only argument I could come up with that they're necessary in some cases might be for performance reasons.

But, I'm not really sure about that. So my question is, would using a global be faster than using a get/set method call?

Community
  • 1
  • 1
GeoffreyF67
  • 11,061
  • 11
  • 46
  • 56

5 Answers5

11

A good modern compiler should inline the get/set method calls such that there's probably no real difference.

In almost any case it's much more important to worry about whether statics/globals are going to cause you a headache than the performance implications, which are going to be nearly undetectable anyway.

Peter
  • 7,216
  • 2
  • 34
  • 46
  • 1
    Compilers inlining getters and setters may be true for C/C++, but readers shouldn't generalize this to other languages as you won't always see this in Java. – Fostah Jan 27 '09 at 20:54
  • 2
    i guess in Java it doesn't matter much anyway. – Johannes Schaub - litb Jan 27 '09 at 20:56
  • litb: Are you mocking Java's performance or do you refer to the non-obvious fact that Java doesnt' allow globals? ;-) – Konrad Rudolph Jan 27 '09 at 21:13
  • You could still have public class member variables and avoid setters and getters. – Fostah Jan 27 '09 at 22:26
  • All the above comments (unlike the answer) is nonsense, sorry to say. You won't see inlining in bytecode, it'll be done by the JIT, and unlike C++ even virtual functions can be inlined. And depending on the benchmark, Java can beat (or be on par with) C, and garbage collection beat malloc/free. Actually, it's easier to inline in Java: in C you must move the function to the header (and when you strive for ABI compatibility, you can't), in Java you have a whole-program profile-guided optimizer for free. How often can you use that in C? And how often the profiling is tied to your input? Never! – Blaisorblade May 05 '10 at 16:16
  • @Blaisorblade `unlike C++ even virtual functions can be inlined` This is wrong. Competent C++ compilers certainly **can** inline `virtual` functions if they can determine the static type of the invoking object, in which case they _devirtualise_ and call the appropriate `override` directly. `in C you must move the function to the header (and when you strive for ABI compatibility, you can't), in Java you have a whole-program profile-guided optimizer for free. How often can you use that in C?` Well, absolutely all the time, in the modern world, where link-time-optimisation is a thing that exists. – underscore_d Aug 26 '16 at 11:36
  • @underscore_d You're probably right that this 2010 comment is no more up-to-date. Also, link-time optimization is whole-program but is not profile-guided optimization (and even PGO can't account for varying inputs that induce varying profiles). Also, Java can still devirtualize even when the target type is not statically known, and even when it is not constant (it adds then a guard to fallback to more generic behavior). That could be done with PGO, subject to the previous limitations. Anyway, my mention of virtual calls was probably already OT. – Blaisorblade Aug 26 '16 at 13:58
  • 1
    @Blaisorblade Fair enough! Thanks for the clarifications. Due to the fundamental differences in the types of languages (native vs VM), I'm sure you're right that there are different strengths on both sides, including VM-bound languages probably having huge advantages in doing more dynamic optimisations. PGO of a kind exists in C++ compilers - such as GCC's feedback-directed optimisation, which [I learned and then rambled about here](http://stackoverflow.com/a/38677725/2757035) - but for the same reason, it must necessarily be far more of a manual, iterative process: compile/profile/compile/zzz – underscore_d Aug 26 '16 at 14:05
3

You could gain more performance yet by writing in assembler. And also lose more time in debugging your code.

It's exactly the same type of trade.

Darron
  • 21,309
  • 5
  • 49
  • 53
  • 1
    Good point, but irrelevant here. Optimizers for high level languages are there to remove the need for such stupid tradeoff. They'll probably never allow you to avoid writing a smart algorithm instead of a poor one, but the function call overhead for small functions is history nowadays (if you declare the function in the header). – Blaisorblade May 05 '10 at 16:14
  • That was essentially my point. Write good code, that's what the compiler writers care about when they write optimizers anyway. – Darron May 12 '10 at 21:16
3

A more appropriate comparison would be between accessing a global (a static) and a local.

Indeed a global is faster because accessing a local requires the variable offset to be added to the value of the stack pointer.

However, you will never, ever need to worry about this. Try concentrating on things that matter, such as making your code be readable, writable, and working.

  • 1
    It really, really, matters in embedded and operating system code where if the code doesn't perform, it doesn't work. And accessing a global is usually slower than accessing a local because you need to go through the GOT. Of course, that depends on the ABI and architecture. – benno Jan 28 '09 at 01:46
  • Locals will usually be faster because they can be allocated in registers (sometimes) and will often have better locality of reference. – Greg Rogers Jan 28 '09 at 14:29
  • 2
    Even if a local is not in a register, whether or not there's a penalty for accessing memory in a stack frame vs an absolute address is quite architecture dependent (especially since the stack frame pointer is generally always already in a register). – Michael Burr Jan 28 '09 at 17:36
  • Good to know guys! I have always assumed that the actual ESP+offset addition is unavoidable. Also I must read about the GOT –  Jan 28 '09 at 18:18
  • The ESP + offset addition is unavoidable, and a decent processor will have devoted transistors for it. So much that optimizers often encode "a*2+c" expressions by using those transistors, through the address unit (with the LEA instruction). I think the GOT is not used for variables in a binary, only for the ones in a shared library. A local is normally faster than a global because (on reasonable stack sizes, without big buffers) it's more likely to be in cache (avoiding ~100 cycles for a cache miss), it takes less space to encode its address, and it can be registerized. – Blaisorblade May 05 '10 at 16:10
1

It might be slightly faster, but not a huge increase in speed. Globals over having getter and setter functions for everything does keep application size down though. Whether this type of size savings is beneficial to your application is relevant to the platform you are targeting. For instance, when developing embedded applications, platforms with limited memory, it can be a viable solution.

Fostah
  • 11,398
  • 10
  • 46
  • 55
1

It depends on the CPU and compiler. On at least one popular PPC chipset, loading a global variable requires extra instructions because it cannot be encoded in a 16-bit relative offset.

Plus, it can take a giant crap on cache locality and/or destroy any optimizations that assume no aliasing. Assuming that globals can increase performance is somewhat naive.

MSN
  • 53,214
  • 7
  • 75
  • 105
  • 1
    On other CPUs like MIPS, there is a register specifically for global variables, so a global access is as fast as a stack access (assuming all your globals fit in 64K. The compiler will usually put small globals there automatically. – Mark James Jan 28 '09 at 01:16
  • 1
    And on ARM you generally need to read the address out of the literal pool, which is not only slow but helps pollute your caches. – benno Jan 28 '09 at 01:47
  • @Mark James, I think that also brings up another issue: polluting the global variable space can make that sort of optimization even harder as well. – MSN Jan 28 '09 at 17:10