odlgroup / odl

Operator Discretization Library https://odlgroup.github.io/odl/
Mozilla Public License 2.0
368 stars 105 forks source link

Improve import odl speed #791

Closed adler-j closed 6 years ago

adler-j commented 7 years ago

It feels like running import odl is becomming so slow you really notice it, and this is irritating.

A short profiling using pyinstrument gave me this modest output from import odl.

2.337 <module>  odl\__init__.py:24
|- 1.392 <module>  odl\diagnostics\__init__.py:18
|  |- 0.824 <module>  odl\diagnostics\operator.py:18
|  |  `- 0.817 <module>  odl\operator\__init__.py:18
|  |     `- 0.792 <module>  odl\operator\default_ops.py:18
|  |        `- 0.785 <module>  odl\space\__init__.py:18
|  |           |- 0.684 <module>  odl\space\entry_points.py:41
|  |           |  |- 0.486 <module>  pkg_resources\__init__.py:15
|  |           |  `- 0.173 iter_entry_points  pkg_resources\__init__.py:698
|  |           `- 0.064 <module>  odl\space\weighting.py:18
|  |              `- 0.040 <module>  scipy\linalg\__init__.py:168
|  |- 0.381 <module>  odl\diagnostics\space.py:18
|  |  `- 0.373 <module>  odl\set\__init__.py:18
|  |     `- 0.359 <module>  odl\set\sets.py:18
|  |        |- 0.150 <module>  odl\util\__init__.py:18
|  |        |  `- 0.104 <module>  odl\util\testutils.py:18
|  |        |     `- 0.095 <module>  pytest.py:4
|  |        |- 0.110 <module>  past\__init__.py:85
|  |        `- 0.085 <module>  numpy\__init__.py:106
|  `- 0.187 <module>  odl\diagnostics\examples.py:18
|     |- 0.130 install_aliases  future\standard_library\__init__.py:441
|     `- 0.056 <module>  future\standard_library\__init__.py:60
|- 0.583 <module>  odl\tomo\__init__.py:18
|  |- 0.509 <module>  odl\tomo\backends\__init__.py:18
|  |  |- 0.464 <module>  odl\tomo\backends\scikit_radon.py:18
|  |  |  `- 0.457 <module>  skimage\transform\__init__.py:1
|  |  `- 0.024 <module>  odl\tomo\backends\astra_setup.py:35
|  `- 0.046 <module>  odl\tomo\geometry\__init__.py:18
|- 0.161 <module>  odl\solvers\__init__.py:18
|  |- 0.123 <module>  odl\solvers\functional\__init__.py:18
|  |  `- 0.103 <module>  odl\solvers\functional\functional.py:19
|  |     `- 0.095 <module>  odl\solvers\nonsmooth\__init__.py:18
|  |        `- 0.070 <module>  odl\solvers\nonsmooth\proximal_operators.py:25
|  |           `- 0.063 <module>  scipy\special\__init__.py:632
|  `- 0.037 <module>  odl\solvers\smooth\__init__.py:18
|- 0.057 <module>  odl\ufunc_ops\__init__.py:18
|  `- 0.057 <module>  odl\ufunc_ops\ufunc_ops.py:18
|     `- 0.044 ufunc_class_factory  odl\ufunc_ops\ufunc_ops.py:161
|- 0.052 <module>  odl\discr\__init__.py:18
|- 0.046 <module>  odl\trafos\__init__.py:18
|  `- 0.026 <module>  odl\trafos\backends\__init__.py:18
`- 0.038 <module>  odl\phantom\__init__.py:18

Here we see that there are a few main culprits in the long loading time:

Of these, I see that we should be able to fix at least the first 3, which should bring startup down to 0.5s which I think is more acceptable.

kohr-h commented 7 years ago

It feels like running import odl is becomming so slow you really notice it, and this is irritating.

Totally agree. Just today I did a much simpler exercise and compared full import times with other packages. Dropping out of Spyder and into IPython on the console and using this function

from time import time
import importlib

def test_import(pkg):
    t_start = time()
    importlib.import_module(pkg)
    t_end = time() - t_start
    print('Imported {} in {} seconds'.format(pkg, t_end))

we have

Results seem to vary a bit depending on IPython vs. plain Python console and IDE vs. plain console. Times for importing ODL:

Probably, caching also plays a role. Earlier today times were much worse. If I remove all .pyc files, ODL imports in 0.5289430618286133 seconds in a non-IDE IPython console.

adler-j commented 6 years ago

This is now significantly improved. Closing.