Is LOAD_GLOBAL really that slow?

Carsten Haese carsten at uniqsys.com
Wed Aug 29 22:33:32 EDT 2007


On Wed, 2007-08-29 at 19:23 -0600, Adam Olsen wrote:
> It seems a common opinion that global access is much slower than local
> variable access.  However, my benchmarks show a relatively small
> difference:
> 
> ./python -m timeit -r 10 -v -s 'x = [None] * 10000
> def foo():
>   for i in x:
>     list; list; list; list; list; list; list; list; list; list' 'foo()'
> 10 loops -> 0.0989 secs100 loops -> 0.991 secs
> raw times: 0.999 0.985 0.987 0.985 0.985 0.982 0.982 0.982 0.981 0.985
> 100 loops, best of 10: 9.81 msec per loop
> 
> ./python -m timeit -r 10 -v -s 'x = [None] * 10000
> def foo():
>   mylist = list
>   for i in x:
>     mylist; mylist; mylist; mylist; mylist; mylist; mylist; mylist;
> mylist; mylist' 'foo()'
> 10 loops -> 0.0617 secs
> 100 loops -> 0.61 secs
> raw times: 0.603 0.582 0.582 0.583 0.581 0.583 0.58 0.583 0.584 0.582
> 100 loops, best of 10: 5.8 msec per loop
> 
> So global access is about 70% slower than local variable access.  To
> put that in perspective, two local variable accesses will take longer
> than a single global variable access.
> 
> This is a very extreme benchmark though.  In practice, other overheads
> will probably drop the difference to a few percent at most.  Not that
> important in my book.

Your comparison is flawed, because the function call and the inner for
loop cause a measurement offset that makes the locals advantage seems
smaller than it is. In the interest of comparing the times for just the
local lookup versus just the global lookup, I think the following
timings are more appropriate:

$ python2.5 -mtimeit -r10 -s"y=42" -s"def f(x): pass" "f(42)"
1000000 loops, best of 10: 0.3 usec per loop
$ python2.5 -mtimeit -r10 -s"y=42" -s"def f(x): x" "f(42)"
1000000 loops, best of 10: 0.331 usec per loop
$ python2.5 -mtimeit -r 10 -s"y=42" -s"def f(x): y" "f(42)"
1000000 loops, best of 10: 0.363 usec per loop

There is no loop overhead here, and after subtracting the function call
overhead, I get 31 nanoseconds per local lookup and 63 nanoseconds per
global lookup, so local lookups are just about twice as fast as global
lookups.

True, whether this difference is significant does depend on how many
name lookups your code makes and how much else it's doing, but if you're
doing a lot of number crunching and not a lot of I/O, the difference
might be significant. Also, even if using local names is only slightly
faster than using globals, it's still not slower, and the resulting code
is still more readable and more maintainable. Using locals is a win-win
scenario.

Hope this helps,

-- 
Carsten Haese
http://informixdb.sourceforge.net





More information about the Python-list mailing list