Skip to main content

Timeline for answer to Why does Python code run faster in a function? by Katriel

Current License: CC BY-SA 3.0

Post Revisions

15 events
when toggle format what by license comment
May 24, 2018 at 0:25 comment added ShadowRanger @Quelklef: Modifying the dict returned by locals is explicitly noted to be unsupported; it can't actually add "real" locals, but the implementation is such that the only way you could dynamically check said "locals" will happen to work, sometimes, on the CPython interpreter; when you first call locals() in a function it makes a mirror of the actual locals as a dict and caches it; if you call locals() again in the same function, you get the same dict. But it's not actually resizing the array of "real" locals.
Dec 5, 2017 at 13:59 comment added Quelklef "This is possible because you can't dynamically add local variables to a function." What about locals()[dynamic_expr] = val?
Oct 25, 2017 at 20:12 comment added Katriel Yes, and because most of the time the slight slowness isn't actually important to the running speed of the program.
Oct 3, 2017 at 10:49 comment added davidtgq When you guys talk about "attribute lookups" foo.bar being slow, does this include using self.my_var inside of a class's methods? If so, then why do people use attribute lookups in classes all the time instead of just using one giant global dictionary?
Jun 16, 2017 at 14:00 history edited Dhia CC BY-SA 3.0
added 150 characters in body
Mar 4, 2014 at 8:45 vote accept thedoctar
Jul 6, 2012 at 14:45 comment added Katriel @thedoctar have a look at the globals() function. If you want more info than that you may have to start looking at the source code for Python. And CPython is just the name for the usual implementation of Python -- so you probably are using it already!
Jul 5, 2012 at 12:10 comment added thedoctar Is there any documentation that global variables are stored in a dict? The other answer links to documentation to STORE_FAST, used to store local variables, which says "Stores TOS into the local co_varnames[var_num]." I don't know what TOS means, but presumably this means the variable is stored in an array. However in the documentation for STORE_NAME, it's not clear a dict is used. Also, I don't know anything about CPython, so would all this information apply to normal python?
Jun 29, 2012 at 19:31 comment added Katriel @Walkerneo Ah, I think I see where the confusion might lie. An attribute lookup like foo.bar is not the same as looking up a variable called "foo.bar"; instead, it first looks up the (local) variable called foo but then searches for "bar" in foo.__dict__. It's this second bit that takes time.
Jun 29, 2012 at 15:15 comment added Katriel Correct. A local variable lookup is a fixed-time pointer. A global lookup is a dict search, but with optimisations (I think the dict code is inlined, for instance). An attribute lookup is just a plain Python dict search.
Jun 29, 2012 at 1:57 comment added Jeremy Pridemore @Walkerneo foo.bar is not a local access. It is an attribute of an object. (Forgive the lack of formatting)def foo_func: x = 5, x is local to a function. Accessing x is local. foo = SomeClass(), foo.bar is attribute access. val = 5 global is global. As for speed local > global > attribute according to what I've read here. So accessing x in foo_func is fastest, followed by val, followed by foo.bar. foo.attr isn't a local lookup because in the context of this convo, we're talking about local lookups being a lookup of a variable that belongs to a function.
Jun 29, 2012 at 0:21 comment added Jeremy Pridemore @Walkerneo The primary conversation going on here is the comparison between local variable lookups within a function and global variable lookups that are defined at the module level. If you notice in your original comment reply to this answer you said "I wouldn't have thought global variable lookups were faster than local variable property lookups." and they're not. katrielalex said that, although local variable lookups are faster than global ones, even global ones are pretty optimized and faster than attribute lookups (which are different). I don't have enough room in this comment for more.
Jun 28, 2012 at 23:18 comment added mowwwalker @JeremyPridemore, The last sentence of katrielalex'x answer is "By the way, global lookups are still pretty optimised. Attribute lookups foo.bar are the really slow ones!". Isn't he saying that global lookups are optimized and faster, but attribute lookups are really slow?
Jun 28, 2012 at 17:17 comment added GDorn This also applies to PyPy, up to the current version (1.8 at the time of this writing.) The test code from the OP runs about four times slower in global scope compared to inside a function.
Jun 28, 2012 at 10:15 history answered Katriel CC BY-SA 3.0