On Mon, May 2, 2016 at 11:36 AM, Steven D'Aprano <steve@pearwood.info> wrote:
On Sun, May 01, 2016 at 09:25:17PM -0400, Random832 wrote:
Is there any reason not to simply implement a performance optimization for the normal syntax?
Yes. You can't assume that myobject is the same object in both statements. A silly toy example:
class MyObject: def deactivate(self): global myobject myobject = None def fire(self): launch_missiles()
myobject.deactivate() myobject.fire()
A more realistic case would be if you have a mutable object:
myobject[1].lookup['key'].property.a() myobject[1].lookup['key'].property.b()
The compiler cannot assume that (myobject[1].lookup['key'].property) will refer to the same thing in the two calls. But the programmer can explicitly do so, using either a temporary variable, or the proposed "using" statement.
If you profile a big program, I expect you'll find that module-level code amounts to a tiny proportion of run-time. Restricting this optimization to function-local names (no nonlocals, no globals - the LOAD_FAST opcode in current CPython) wouldn't materially harm it, and it would make the code a lot easier to reason about. The only possible issue that I can see is with an inner function messing with the outer function: def f(): obj = MyObject() def switch_obj(): nonlocal obj obj = MyObject() return 5 obj.attr1 = switch_obj() obj.attr2 = 42 return obj But a quick check with dis.dis(f) shows that this, too, uses LOAD_DEREF, so that should be safe - a byte-code transformation should safely be able to look for the LOAD_FAST and depend on it not changing (short of insane shenanigans - if you mutate sys._getframe().f_locals to tamper with another function's locals, you deserve all you get... and I'm not sure if it'd even work). This would be restricted to lookups on simple names. Frankly, I wouldn't expect anything else. If you want to call "myobject[1].lookup['key'].property.a" and "etc etc .b", you should probably be giving that a name *for the benefit of humans*, never mind about the interpreter! And if you want it optimized, definitely assign that to a local name. ChrisA