On Thu, May 27, 2021 at 04:37:10PM +0200, Ronald Oussoren wrote:
One common use for function defaults is to optimize function lookups to local variables instead of global or builtins:
def func(arg, len=len): # now len is a fast local lookup instead of a slow name lookup
That’s a CPython performance hack,
No it isn't. I think we can assume than any non-crappy implementation will have faster access to locals than globals and builtins, or at least no worse. So it is a fair expectation that any time you can turn a global lookup into a local lookup, you should have some performance benefit.
Function parameters are guaranteed to be local variables. Default values are guaranteed to be evaluated once, at function definition time. These are language guarantees not CPython implementation details.
The precise performance benefit will, of course, vary from VM to VM, but we should expect that any serious implementation should give some performance benefit.
(All the usual optimization caveats still apply: measure, don't guess, etc. Optimizations that work in theory may not always work in practice, yadda yadda yadda.)
and “static” would just introduce a different performance hack. IIRC there has been work in recent versions of CPython to reduce the need for that hack by caching values in the VM.
This trick has worked all the way back to Python 1.5, maybe even longer, so I think it's pretty stable against changes in the interpreter. But for the sake of the argument I'll accept that some future performance improvements that reduces the need for the `len=len` trick to negligible amounts.
Static storage in functions will still be useful. Any time you need data to persist from one function call to another, you can either:
- expose your data in a global variable; - or as a function attribute; - use a mutable function default; - rewrite your function as a callable instance; - obfuscate your function by wrapping it in a closure;
all of which are merely work-arounds for the lack of proper static locals.