
Performance -----------
Performance with this PEP should be favorable. In general, resources are only consumed on demand—"you only pay for what you use".
Nice!
There are three scenarios to consider:
* the runtime cost when annotations aren't defined, * the runtime cost when annotations are defined but *not* referenced, and * the runtime cost when annotations are defined *and* referenced.
Note: The first two cases are major. Many codes doesn't have annotations. Many codes use annotations just only for documentation or static checker. In the second scenario, the annotations must be very cheap. Its cost must be comparable with docstrings. Otherwise, people can not use annotation freely in a large codebase. Or we must provide an option like -OO to strip annotations.
We'll examine each of these scenarios in the context of all three semantics for annotations: stock, PEP 563, and this PEP.
When there are no annotations, all three semantics have the same runtime cost: zero. No annotations dict is created and no code is generated for it. This requires no runtime processor time and consumes no memory.
When annotations are defined but not referenced, the runtime cost of Python with this PEP should be slightly faster than either original Python semantics or PEP 563 semantics. With those, the annotations dicts are built but never examined; with this PEP, the annotations dicts won't even be built. All that happens at runtime is the loading of a single constant (a simple code object) which is then set as an attribute on an object. Since the annotations are never referenced, the code object is never bound to a function, the code to create the dict is never executed, and the dict is never constructed.
Note that PEP 563 semantics allows more efficient implementation. Annotation is just a single constant tuple, not a dict. We already have the efficient implementation for Python 3.10. The efficient implementation in 3.10 can share tuples. If there are hundreds of methods with the same signature, annotation is just a single tuple, not hundreds of tuples. This is very efficient for auto generated codebase. I think this PEP can share the code objects for same signature by removing co_firstlineno information too. Additionally, we should include the cost for loading annotations from PYC files, because most annotations are "load once, set once". Loading "simple code object" from pyc files is not so cheap. It may affect importing time of large annotated codebase and memory footprints. I think we need a reference application that has a large codebase and highly annotated. But we need to beware even if the large application is 100% annotated, libraries used are not 100% annotated. Many libraries are dropping Python 2 support and start annotating. The cost of the annotations will become much more important in next several years.