[Python-ideas] RFC: PEP: Add dict.__version__

Victor Stinner victor.stinner at gmail.com
Sat Jan 9 18:08:56 EST 2016


2016-01-09 23:18 GMT+01:00 Terry Reedy <tjreedy at udel.edu>:
> But as near as I can tell, your proposal cannot detect all relevant changes
> unless one is *very* careful.  A dict maps hashable objects to objects.
> Objects represent values.  So a dict represents a mapping of values to
> values.  If an object is mutated, the object to object mapping is not
> changed, but the semantic value to value mapping *is* changed. In the
> following example, __version__ twice gives the 'wrong' answer from a value
> perspective.

dict.__version__ is a technical solution to implement efficient guards
on namespace. You are true, that it's not enough to detect any kind of
change. For example, to inline a function inside the same module, we
need a guard on the global variable, but also a guard on the function
itself. We need to disable the optimization if the function code
(func.__code__) is modified. Maybe a guard is also needed on default
values of function parameters. But guards on functions don't need to
modify CPython internals. It's already possible to implement efficient
guards on functions.

> Replacing a call with a return value assumes that the function is immutable,
> deterministic, and without side-effect.

that the function is deterministic and has no side-effect, yep.

>  Perhaps this is what you meant by
> 'pure'.  Are you proposing to provide astoptimizer with either a whitelist
> or blacklist of builtins that qualify or not?

Currently, I'm using a whitelist of builtin functions which are known
to be pure. Later, I plan to detect automatically pure functions by
analyzing the (AST) code.

> Aside from this, I don't find this example motivational.  I would either
> write '3' in the first place or write something like "slen =
> len('akjslkjgkjsdkfjsldjkfs')" outside of any loop.  I would more likely
> write something like "key = 'jlkjfksjlkdfjlskfjkslkjeicji'; key_len =
> len(key)" to keep a reference to both the string and its length.  Will
> astoptimizer 'propogate the constant' (in this case 'key')?

FYI I already have a working implementation of the astoptimizer: it's
possible to run the full Python test suite with the optimizer.
Implemented optimizations:
https://faster-cpython.readthedocs.org/fat_python.html#optimizations

Constant propagation and constant folding optimizations are
implemented. A single optimization is not interesting, It's more
interesting when you combine optimizations. Like constant propagation
+ constant folding + loop unrolling.

> The question in my mind is whether real code has enough pure builtin calls
> of constants to justify the overhead.

Replacing len("abc") with 3 is not the goal of FAT Python. It's only
an example simple to understand.

> How often is this useful in modern real-world Python code?  Many old uses of
> range have been or could be replaced with enumerate or a collection
> iterator, making it less common than it once was.

IMHO the optimizations currently implemented will not provide any
major speedup. It will become more interesting with function inlining.
The idea is more to create an API to support pluggable static
optimizations.

> How often is N small enough that one wants complete versus partial
> unrolling?  Wouldn't it be simpler to only use a (specialized) loop-unroller
> where range is known to be the builtin?

What is the link between your question and dict.__version__?

Victor


More information about the Python-ideas mailing list