cat /dev/brain |

Don't use setuptools entry points…

published on Saturday, February 25, 2017

…for small scripts.

Setuptools provides a feature called entry points that can be used to define for which functions the setup script should create executables – or to register plugins. This is pretty cool (and even works on windows)!

The downside is that entry points have insanely bad startup times: A simple hello-world program invoked through an entry point takes an embarrassing 0.2 seconds (!!!) to run on my system – and even much longer (about 2-5 seconds) if loaded for the first time.

Is this overhead due to loading the python environment itself? Let's have a look. An executable for an entry point generated by setuptools generally does something like this:

from pkg_resources import load_entry_point
load_entry_point('hello_world', 'console_scripts', 'hello-world')()

The same application runs almost instantaneously, if we replace this as follows:

import hello_world
hello_world.main()

In fact, the main cost is from importing pkg_resources. Try it yourself:

% time python -c 'import pkg_resources'
python -c 'import pkg_resources'  0.19s user 0.02s system 99% cpu 0.215 total

% time python -c 'import hello_world'
python -c 'import hello_world'  0.02s user 0.00s system 92% cpu 0.025 total

The issue is known but I'm not sure anyone is going to fix it anytime soon.

So what to do about it? For now I'm using fast-entry_points which patches the setuptools script generator with a replacement as shown above.

Spread the word!

This entry was tagged bug, deployment, performance, python, rant and setuptools

blog comments powered by Disqus