Which is more efficient: Python docstrings or type-hints?
Asked Answered
A

2

29

I want to add some support for auto-completion to my Python code with Jedi. This can be done by using either function docstrings or type hints (or both).

def function_with_types_in_docstring(param1, param2):
    """Example function with types documented in the docstring.
  
    :type param1: int
    :type param2: str
    :rtype: bool
    """

def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
    """Example function with PEP 484 type annotations."""

Which method of documenting types adds less overhead in terms of memory usage and running time? I'm interested in the efficiency of the Python code itself first, then Jedi.

Asturias answered 6/6, 2017 at 12:21 Comment(0)
S
29

TL;DR: Use type annotations, they are awesome.

For both Python and jedi it does not make a difference wheter you use docstrings or function annotations. Both performance and memory impact should not be noticeable. There is obviously a small runtime overhead in both cases.

Docstrings are simply converted to Python strings and stored in the attribute function.__doc__. This takes a few bytes of memory, but you shouldn't care about that. A very large docstring of 1000 characters still only uses 1kB of RAM. If your memory is constrained you may simply use python -o to get rid of docstrings (and asserts as well, look it up).

Type annotations (PEP 484, e.g. def foo(a: int) -> str:) are stored in function.__annotations__:

>>> def foo(bar: int): pass
... 
>>> foo.__annotations__
{'bar': <class 'int'>}

These annotations obviously also use some space (but even less than docstrings). However they have no influence on runtime execution (except if you explicitly play with __annotations__.

I would recommend you to use type annotations. They have been introduced, because of static analysis/IDEs and are definitely the future when it comes to documenting your types. There's also a lot of work happing on mypy, jedi and other tools to make type annotations more usable in verifying programs. Use type annotations already and you will be ready for the future.

Scottie answered 6/6, 2017 at 14:26 Comment(3)
"even less than docstrings": note that annotations are now stored as strings (docs.python.org/3.7/whatsnew/…), so the space savings are minimal. This change was actually done because annotations were making startup slower.Outmost
While it makes sense to use type annotations it doesn't solve the issue. Since docstring still make sense to describe what a parameter is used for (in words) we need both: type annotations for linters and docstrings for humans. I'm not aware of any PEP that suggests how to merge both so DRY is respected and we can just omit types when writing docstrings if the function is using type hints.Arroba
@masi Yes you need docstrings, but you don't need them for types. There's easy way to generate docs that use annotations.Scottie
C
0

Not a proper answer but for the autocompletion part alone, neither docstrings nor type hints are required. Also note that you'll find very very very few "type-hinted" code in the stdlib and 3rd part packages anyway.

Finally and FWIW : I've been using Jedi in Emacs for quite a few years now and never had performance issues so I don't think you should really worry...

Carte answered 6/6, 2017 at 12:41 Comment(2)
Interesting. From my experience, most of the time Jedi only starts auto-completing after I add a type hint or a proper docstring. Anyway, the question was not only about the efficiency of Jedi, but also the Python code itself :)Asturias
"the question was not only about the efficiency of Jedi, but also the Python code " => then you may want to clarify your question. But anyway: docstrings have no noticeable impact AFAICT. Can't tell about type hints but they shouldn't have much impact either.Carte

© 2022 - 2024 — McMap. All rights reserved.