4

Following up on this answer: https://stackoverflow.com/a/17366561/1982118

On my macbook pro 2015 (2.8 GHz Intel Core i7) with python 3.6, I get:

python3 -m timeit -s 'import inspect' 'inspect.currentframe().f_code.co_name'
>>> 1000000 loops, best of 3: 0.428 usec per loop

python3 -m timeit -s 'import sys' 'sys._getframe().f_code.co_name'

>>> 10000000 loops, best of 3: 0.114 usec per loop

using sys._getframe() is 4 times faster than inspect.currentframe().

How come?

user1982118
  • 442
  • 1
  • 4
  • 13

1 Answers1

5

Assuming that the question is about CPython, you can see the implementation of inspect.currentframe here:

def currentframe():
    """Return the frame of the caller or None if this is not possible."""
    return sys._getframe(1) if hasattr(sys, "_getframe") else None

The function calls hasattr in addition to sys._getframe, thus it has to be slower.

hasattr works by attempting to get the attribute and catching the AttributeError exception, if that fails. The _getframe attribute exists and is retrieved again, thus adding to the overhead.

vaultah
  • 44,105
  • 12
  • 114
  • 143
  • 2
    Additionally, `getattr(foo, "bar")` is often slower than `foo.bar` (~2x on my machine), I believe because it has to do more work at runtime rather than when compiling bytecode, so you pay more than double for checking twice. – Ben Kraft Jul 19 '17 at 16:57