Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid entry point lookups in Node/Group metaclasses #6091

Merged
merged 4 commits into from
Aug 31, 2023

Conversation

danielhollas
Copy link
Collaborator

@danielhollas danielhollas commented Jul 27, 2023

It turns out a big part of why aiida.orm import is so slow are costly entry point lookups
in AbstractNodeMeta and GroupMeta metaclasses.

Commit 1: _plugin_type_string and _query_type_string

These class attributes require a look up whether the Node class has a
registered entry point which can have a non-negligible cost. These
attributes were defined in the AbstractNodeMeta class, which is the
metaclass of the Node class, which would cause this code to be
executed as soon as the class was imported.

Here, the AbstractNodeMeta metaclass is removed. The
_plugin_type_string and _query_type_string class attributes are
changed to class properties. The actual value is stored in the private
attribute analog which is defined lazily the first time the property is
accessed.

Commit 2: __type_string

This attribute was defined in the GroupMeta metaclass.
Because this was the only purpose of this metaclass,
we can fully remove it and use the same strategy as above.

Commit 3: Avoiding aiida.cmdline import

There are some further entry point lookups in metaclasses defined in aiida.cmdline used for the click interface.
It's not that clear how to get rid of those, but here we at least avoid importing aiida.cmdline from aiida.orm and aiida.manage,
which also speeds up import aiida.

With this last change, there are no entry point lookups during aiida.orm import. 🎉

Benchmarks

TODO: I will add benchmarks shortly...

@danielhollas
Copy link
Collaborator Author

Benchmarks against the current main branch

import aiida

$ hyperfine -w 2 "PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida'" "python -c 'import aiida'"
Benchmark 1: PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida'
  Time (mean ± σ):     287.6 ms ±  23.5 ms    [User: 257.4 ms, System: 29.5 ms]
  Range (minmax):   262.2 ms317.5 ms    10 runs
 
Benchmark 2: python -c 'import aiida'
  Time (mean ± σ):     239.6 ms ±   9.8 ms    [User: 213.5 ms, System: 25.5 ms]
  Range (minmax):   223.5 ms254.1 ms    12 runs
 
Summary
  'python -c 'import aiida'' ran
    1.20 ± 0.11 times faster than 'PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida''

import aiida.orm

$ hyperfine -w 2 "PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida.orm'" "python -c 'import aiida.orm'"
Benchmark 1: PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida.orm'
  Time (mean ± σ):     997.2 ms ± 199.5 ms    [User: 1530.3 ms, System: 711.7 ms]
  Range (minmax):   735.8 ms1360.8 ms    10 runs
 
Benchmark 2: python -c 'import aiida.orm'
  Time (mean ± σ):     503.3 ms ±   9.8 ms    [User: 1029.0 ms, System: 717.3 ms]
  Range (minmax):   491.5 ms522.9 ms    10 runs
 
Summary
  'python -c 'import aiida.orm'' ran
    1.98 ± 0.40 times faster than 'PYTHONPATH=/home/hollas/atmospec/aiida-core-main python -c 'import aiida.orm''

@danielhollas
Copy link
Collaborator Author

The one failing Rabbitmq test is confusing. It only happened for RMQ version 3.7, but it happened twice already so I am not sure if it is just a flaky test or not.

@danielhollas
Copy link
Collaborator Author

@sphuber @unkcpz could you take a look? (I cannot assign reviewers on this repo apparently)

@sphuber sphuber self-requested a review August 31, 2023 16:59
@sphuber sphuber force-pushed the fix/lazy-node-metaclass-dh branch from ea71dc4 to cce6d05 Compare August 31, 2023 17:20
sphuber and others added 4 commits August 31, 2023 19:24
These class attributes require a look up whether the `Node` class has a
registered entry point which can have a non-negligible cost. These
attributes were defined in the `AbstractNodeMeta` class, which is the
metaclass of the `Node` class, which would cause this code to be
executed as soon as the class was imported.

Here, the `AbstractNodeMeta` metaclass is removed. The
`_plugin_type_string` and `_query_type_string` class attributes are
changed to class properties. The actual value is stored in the private
attribute analog which is defined lazily the first time the property is
accessed.
This is a follow-up on previous commit aiming to speedup the import of
the `aiida.orm` by avoiding costly entry point lookups.

Here we completely remove the `GroupMeta` metaclass and move its logic
into the `_typestring` classproperty, which avoids the code being
executed on import while being backwards compatible.
This forces the import of `aiida.cmdline` in `aiida.orm` which doesn't
just slow down, but also is conceptually wrong. The problem of the
`with_dbenv` decorator is also that it cannot be imported inside a
method to avoid the import cost when importing `aiida.orm` but has to be
imported at the top in order to be used.
@sphuber sphuber force-pushed the fix/lazy-node-metaclass-dh branch from cce6d05 to 9301cdd Compare August 31, 2023 17:24
@sphuber
Copy link
Contributor

sphuber commented Aug 31, 2023

There were two more top-level imports of aiida.cmdline in aiida.orm that I also removed. I was a bit hesitant to merge this, since it is potentially a significant change and could break things without us noticing. But let's merge. If there is a problem, hopefully we will find it before release by running of the main branch.

Copy link
Contributor

@sphuber sphuber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @danielhollas

@sphuber sphuber merged commit 35c57b9 into aiidateam:main Aug 31, 2023
@danielhollas danielhollas deleted the fix/lazy-node-metaclass-dh branch August 31, 2023 18:30
@danielhollas
Copy link
Collaborator Author

Thanks @sphuber! I'll work on submitting the other PRs which should be less risky than this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants