catkin / catkin_tools

Command line tools for working with catkin
Apache License 2.0
163 stars 146 forks source link

pkg_resources.entry_points is really slow #297

Open jbohren opened 8 years ago

jbohren commented 8 years ago

On my 2.9Ghz i7 with an EVO850 SSD running Ubuntu 12.04:

$ time python -c 'from pkg_resources import load_entry_point'
python -c 'from pkg_resources import load_entry_point'  0.14s user 0.01s system 97% cpu 0.152 total

This means that using calls to the catkin script in tab-completion is a very laggy experience, and explains why there's a ubiquitous >200ms latency when running catkin commands. I think as it stands, catkin_tools is over-using the entry_points interface. For example it's not necessary for the main catkin command, nor is it really necessary for the built-in verbs.

I think the tool could be much more responsive if we used an alternative to entry_points for the verbs and build types. For example, mercurial uses a simple interface in .hgrc to specify plugins explicitly, and I think we would be better off using a system like that.

Currently catkin creates ~/.config/catkin and catkinrc could contain something like:

verbs:
  lint: catkin_lint.main
build-types:
  catkin: catkin_tools.build_types.catkin
  cmake: catkin_tools.build_types.cmake
  ament: ament_pkg.catkin_plugin 

Loading and reading a YAML file or INI is under 50ms:

$ time python -c 'import yaml; f = open(".config/catkin/verb_aliases/00-default-aliases.yaml","r"); print(yaml.load(f)); f.close();' 
{'bt': 'b --this', 'p': 'create pkg', 'b': 'build', 'ls': 'list', 'install': 'config --install', 'test': 'build --verbose --make-args test --', 'run_tests': 'build --verbose --catkin-make-args run_tests --'}
python -c   0.04s user 0.02s system 94% cpu 0.064 total

Related: #295, #209

ninjaaron commented 8 years ago

I wrote a tiny module called fastentrypoints that monkey patches the mechanism behind entry_points to generate scripts that don't import pkg_resources.

https://github.com/ninjaaron/fast-entry_points

mikepurvis commented 7 years ago

Unless I'm misunderstanding something, the fast entry points script will only improve things for the initial bootstrap from script into module— we also use pkg_resources here for handling plugins, so to really get the benefit, we'd need to do a couple things:

Alternatively, we could do the caching / catkinrc option proposed above, which is probably actually a better fit for handling completion. The trick would be avoiding needing to ever have the user manually refresh the file, which I think could be achieved using rules similar to the above:

wjwwood commented 7 years ago

@mikepurvis that all sounds right to me. Spinning off a daemon each time to update the file sounds scary, but I've done it the past with bloom (to check the version and report when you're out of date) and other tools use something like this to accelerate certain tasks. For example, bazel does this, but they actually leave theirs running for a long time (they call it a "long-lived server process"):

https://bazel.build/versions/master/docs/bazel-user-manual.html#client/server

So I think it's a good idea, with precedent.

ltalirz commented 5 years ago

just to mention for people who are still interested in this topic: we use the reentry package for this purpose - it's not yet perfect but it's a start.

The trick would be avoiding needing to ever have the user manually refresh the file

reentry does this via a post-install hook in the setup.py (but it's not ideal: e.g. it doesn't work for installing wheels and it won't remove things from the cache when you uninstall).

graingert commented 1 year ago

pkg_resources is now deprecated. importlib.metadata is available for loading entrypoints in all supported (3.8+) versions of python