[Python-Dev] optimizing non-local object access (original) (raw)

Skip Montanaro skip@pobox.com (Skip Montanaro)
Thu, 9 Aug 2001 12:58:37 -0500


Jeremy> My worry about your approach is that the track-object opcodes
Jeremy> could add a lot of expense for objects only used once or twice.
Jeremy> If the function uses math.sin inside a loop, it's an obvious
Jeremy> win.  If it uses it only once, it's not so clear.

Even if math.sin is used just once you swap a LOAD_GLOBAL/LOAD_ATTR pair for a TRACK_OBJECT/LOAD_FAST/UNTRACK_OBJECT trio, so the hit you take shouldn't be terrible. (My assumption is that the register/unregister cost is fairly low and the actual notification/update code will almost never be executed.) You break even in total instructions executed with two accesses and win after that. In addition, this might be a strategy left for an optimization pass that would only make the change if the LOAD_ATTR and/or LOAD_GLOBAL instructions are executed in a loop.

Jeremy> To be more concrete: The math module would store the sin name in
Jeremy> slot X.  The first time the foobar module used math.sin it would
Jeremy> lookup the slot of sin in the math table.  The foobar module
Jeremy> would store a pointer to math's fast globals and the index of
Jeremy> the sin slot.  Then math.sin would be accessed via a single
Jeremy> opcode that used the stored information.

Unfortunately, the code that uses math.sin can't know that math is a module. It might be an instance with a sin attribute. Even worse, because of Python's dynamic nature, what the name "math" is bound to can change. You can't assume it will always be bound to a module object, even if it is the first time you set things up. I think you have to work with names and name bindings. I don't think you can make assumptions about what the names are bound to.

The handwaving bit in my post was there because I am not familiar enough with the various possibilities for name rebinding. Does it all boil down to PyDict_SetItem or PyObject_SetAttr as I suspect? Are those functions too low-level, that is, have the names been forgetten completely at that point? If so, perhaps STORE_GLOBAL and STORE_ATTR would have to be modified to use PyDict_SetItemString and PyObject_SetAttrString instead.

Skip