On Apr 8, 2020, at 09:57, Guido van Rossum <gu...@python.org> wrote:
> 
> 
> Look at the following code.
> 
> def foo(a, b):
>     x = a + b
>     if not x:
>         return None
>     sleep(1)  # A calculation that does not use x
>     return a*b
> 
> This code DECREFs x when the frame is exited (at the return statement). But 
> (assuming) we can clearly see that x is not needed during the sleep 
> (representing a big calculation), we could insert a "del x" statement before 
> the sleep.
> 
> I think our compiler is smart enough to find out *some* cases where it could 
> safely insert such del instructions.

It depends on how much you’re willing to break and still call it “safely”.

    def sleep(n):
        global store
        store = inspect.current_frame().f_back.f_locals['x']

This is a ridiculous example, but it shows that you can’t have all of Python’s 
dynamic functionality and still know when locals are dead. And there are less 
ridiculous examples with different code. If foo actually calls eval, exec, 
locals, vars, etc., or if it has a nested function that nonlocals x, etc., how 
can we spot that at compile time and keep x alive?

Maybe that’s ok. After all, that code doesn’t work in a Python implementation 
that doesn’t have stack frame support. Some of the other possibilities might be 
more portable, but I don’t know without digging in further.

Or maybe you can add new restrictions to what locals and eval and so on 
guarantee that will make it ok? Some code will break, but only rare “expert” 
code, where the authors will know how to work around it.

Or, if not, it’s definitely fine as an opt-in optimization: decorate the 
function with @deadlocals and that decorator scans the bytecode and finds any 
locals that are dead assuming there’s no use of locals/eval/cells/etc. and, 
because you told it to assume that by opting in to the decorator, it can insert 
a DELETE_FAST safely.

People already do similar things today—e.g., I’ve (only once in live code, but 
that’s still more than zero) used a @fastconst decorator that turns globals 
into consts on functions that I know are safe and are bottlenecks, and this 
would be no different. And of course you can add a recursive class decorator, 
or an import hook (or maybe even a command line flag or something) that enables 
it everywhere (maybe with a @nodeadlocals decorator for people who want it 
_almost_ everywhere but need to opt out one or two functions).

Did Victor Stinner explore this as one of the optimizations for FAT Python/PEP 
511/etc.? Maybe not, since it’s not something you can insert a guard, 
speculatively do, and then undo if the guard triggers, which was I think his 
key idea.

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OIGCRV464VJW3FRRBBK25XSNQYGWID7N/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to