[Python-Dev] optimizing non-local object access
email@example.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
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.