[Python-ideas] Add specialized bytecode with guards to functions

Random832 random832 at fastmail.com
Wed Oct 21 19:35:32 CEST 2015


Victor Stinner <victor.stinner at gmail.com>
writes:
> You are changing the semantic of Python. In Python, you should be able
> to override builtin functions.

What I am proposing is a generalized way to add objects that do not have
a literal to a function's constants pool. The global name within the
first version of the function is simply used as a placeholder for
loading the new constant.

It could just as easily be something like

def foo():
   return _1(abc)

foo = add_consts(foo, {'_1':len})

> Binding a global name to a local name is a known trick to optimize a
> function, but you have to write it explicitly, and again you loose the
> ability to override len.

This would also have to be written explicitly, and the whole point is to
lose the ability to override things. Explicitly.

> Example:
>
> def f(len=len):
>    return len("abc")
>
> Here len becomes a fast local variable.

It'd be even faster as a constant, and that way people couldn't call it
as f(len=whatever) [so an optimizer doesn't have to deal with the
possibility of people doing that]

>> Decorators could be included to freeze only built-ins, to freeze all
>> globals and built-ins, or to have a list of names to exclude. So you
>> could have @freeze_builtins or @freeze_all_globals for each function
>> that needs heavy optimization.
>
> I cited "previous attempts" which failed.
>
> What you describe is close to my "readonly" attempt which tried to
> make module and type namespaces readonly:
> https://hg.python.org/sandbox/readonly/file/tip/READONLY.txt

This would apply to the function, not the namespace.

> Making namespaces read-only simply doesn't work. It's very common to
> modify namespaces. I added callbacks to disable optimizations when a
> namespace is modified. But this design doesn't scale: you add a
> complexity of O(n) when a namespace is modified, even if optimized
> functions are never called.

Nothing happens when a namespace is modified, because the function is no
longer using the namespace in any form. This adds to the cost of
defining a function, but in most cases (I'm not 100% sure of the
semantics for nested functions, let alone the implementation) this could
be done at compile time, so it would be a one-time cost.



More information about the Python-ideas mailing list