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

Increased build time with autosummary templates #889

Closed
tupui opened this issue Aug 24, 2022 · 59 comments · Fixed by #1609
Closed

Increased build time with autosummary templates #889

tupui opened this issue Aug 24, 2022 · 59 comments · Fixed by #1609

Comments

@tupui
Copy link
Contributor

tupui commented Aug 24, 2022

In some cases, using autosummary templates causes a significant increase in build time. This is particularly true for the scipy and nump docs (link to autosummary templates scipy uses).

I have verified this using this version of SciPy scipy/scipy#16660 and built the documentation on main and also with changes from #878. In both cases I run with and without templates.

originally discussed in #878,

@choldgraf
Copy link
Collaborator

Thanks for opening this! Can you try one other thing:

  • Build with the autosummary template
  • Count how many extra pages are created as part of this in the sidebar
  • Remove the autosummary template
  • Manually add that number of pages to the docs
  • Re-build and see if it takes the same length

The goal here would be to test whether this is related to autosummary specifically, or just because of the large number of "stub files" that autosummary generates.

@tupui
Copy link
Contributor Author

tupui commented Jan 6, 2023

@QuLogic @timhoffm I see that for Matplotlib you have some templates and are using latest. Did you notice any build time increase?

@timhoffm
Copy link
Contributor

timhoffm commented Jan 6, 2023

I cannot really say. Matplotlib doc build times are annoyingly slow (up to 12min). They vary quite strongly for local builds depending on clean/non-clean builds, the environment I use (likely versions of sphinx, sphinx-gallery, pydata-sphinx-theme, python version, ...), other unknown factors. There's too much noise in the data, so that I cannot say off the top of my head whether latest pydata-sphinx-theme makes a difference.

Maybe @QuLogic has some statistics from CI runs?

@tupui
Copy link
Contributor Author

tupui commented Jan 9, 2023

Thanks for the feedback. Interesting because for SciPy starting from 0.10 it's doubling our build time.

@choldgraf
Copy link
Collaborator

Hey all - the latest state of getting around this is documented at this docs link:

I don't think it's on the roadmap of this project to make any more technical changes to address this, unless the suggestions above really don't work for many people.

@tupui
Copy link
Contributor Author

tupui commented Mar 1, 2023

I am sorry but I am a bit confused here as the issue is not linked to the TOC.

Both NumPy and SciPy have seen their build time literally double making the CI go above the hour. Until this is resolve we are stuck with 0.9 and cannot update.

If now you are saying this project won't do anything about the build issues with templates, then this should be documented and on our side we need to not use templates anymore so we can update the theme.

@choldgraf
Copy link
Collaborator

choldgraf commented Mar 1, 2023

I think (?) It is related to the sidebar TOC. The problem is that this theme nests all of it's sub-pages in the sidebar dropdowns. When there is an extension like autodoc that generates thousands of extra pages then it means that we now have n_pages + thousands_of_autodoc_pages * n_pages + thousands_of_autodoc_pages references to resolve and this is what really slows down the builds. Am I not understanding this issue properly?

@tupui
Copy link
Contributor Author

tupui commented Mar 1, 2023

No we limit to 2 levels on the ref pages.

I will try again tomorrow to build with our newest version as the toc is even empty now.

@lwasser
Copy link
Contributor

lwasser commented Mar 1, 2023

commenting here to be able to watch this thread. i'm going to test out templates as well and will see what happens to our build (our docs are tiny however compared to what @tupui is dealing with).

@choldgraf
Copy link
Collaborator

choldgraf commented Mar 2, 2023

Just a thought @tupui it would be helpful if you provided more context and a minimum reproducible example in the top comment. I know you have cross linked to some discussion in the PR, but it makes it easier to read and understand if it's all contained within the relevant issue. For example, what are autosummary templates? How can someone add them themselves to test it out? What's the simplest template that still causes a slowdown?

One other thing that might be helpful. Check out this profile job in our noxfile:

https://github.com/pydata/pydata-sphinx-theme/blob/main/noxfile.py#L122

You might be able to repurpose that for the scipy docs to see if we can pinpoint the function that is taking up all the extra time.

@tupui
Copy link
Contributor Author

tupui commented Mar 2, 2023

I updated the linked PR to build with the latest version of the theme. It's still timing out and the build time goes above 40 mins.

Sorry I won't spend more time repeating what I said elsewhere and on discord. I already gave a reproducer. Yes it's big as it's SciPy's doc (still, @drammock was able to reproduce), also, as I said in the linked issue, I could not reproduce with a smaller chunk of SciPy's doc.

And as I said multiple times, I am not at all a web dev nor Sphinx expert. I just know my way around to make things work or adjust a bit according to my needs. I already spent a considerable amount of time on this issue and from all my report I think I showed enough effort...

One other thing that might be helpful. Check out this profile job in our noxfile:

You might be able to repurpose that for the scipy docs to see if we can pinpoint the function that is taking up all the extra time.

I don't get what I would be supposed to do here.

@choldgraf
Copy link
Collaborator

Sorry I won't spend more time repeating what I said elsewhere and on discord.

Sorry, I am just providing suggestions to make this issue easier for others to understand and take action on, in the hopes that it more quickly resolves your problem. I appreciate the scipy docs have this problem but I think a minimal reproducible example would be much more realistic for somebody to act on. I understand if you don't have time, maybe somebody else can figure out the minimal sphinx setup that reproduces this.

We are all volunteers here, working on nights and weekends to maintain this theme, so the more complex something is, the lower the chance that people have time to get to it.

I don't get what I would be supposed to do here.

I think the relevant line is here:

session.run(
*f"py-spy record -o {output} -- sphinx-build {path_tmp} {path_tmp_out}".split() # noqa
)

This uses py-spy to profile the build process of sphinx. It outputs an SVG that shows what things took the most time. You or somebody else could run this once with an old version of the theme, and once with a new version of the theme, and compare the two.

@tupui
Copy link
Contributor Author

tupui commented Mar 2, 2023

We are all volunteers here, working on nights and weekends to maintain this theme, so the more complex something is, the lower the chance that people have time to get to it.

We are all on the same wagon 😉 I don't think you need to use this argument with me... Hopefully the new CZI grant will help to mitigate that.

I think I did my fair share by advocating for using this theme in all places and helped raised a few things and made PRs when I could and I did my best so far with this specific issue. But it's past 4 versions now that both SciPy and NumPy cannot use. Hence, I am not sure why you are not considering this to have a higher priority on the list.

@12rambau
Copy link
Collaborator

12rambau commented Mar 2, 2023

It's low on our priority list because we have the same problem as you do: we don't understand... and no other projects have reported such an increase (pandas, geopandas, bokeh, geodatacube). So without a reproducible example that's hard to tell if it's coming from us, autodoc, autosummary, Sphinx version etc...

What I can offer is to do what @choldgraf just suggested tonight (while playing mario kart for low intervention supervision) and post the results here. I will also try to remove the templates to see if it's improving anything.

See you in 5-6 hours

@tupui
Copy link
Contributor Author

tupui commented Mar 2, 2023

Thanks for stopping by @12rambau. As of now I tested this on various versions of Sphinx (and other versions for various deps.) I could see every time that removing autosummary templates gives a 2x performance improvement (so back to previous build time.)

@choldgraf
Copy link
Collaborator

I think an important thing to try is removing each template one by one, and seeing if a specific template is causing the slowdown. If you can pinpoint that then it'll be easier to debug what stuff it is calling.

And yes unfortunately this issue is a combination of "small N of projects reporting, and I have no idea what's going on + the scipy docs build process is very confusing to me as well".

@12rambau
Copy link
Collaborator

12rambau commented Mar 2, 2023

I got swamped with work, I'll see what I can do this WE

@drammock
Copy link
Collaborator

drammock commented Mar 7, 2023

Sorry I won't spend more time repeating what I said elsewhere and on discord.

Discord? Whatever you said on Discord was in a server that we (or at least I) am not a member of. Please don't expect us to monitor Scipy's internal communication channels (even if they're public).

I've just given another try at reproducing this. Here's what I did:

  1. updated my clone of scipy (git fetch --all --prune; git switch main; git merge --ff-only upstream/main)
  2. created a new branch off of current main (scipy/scipy@81f84c818) and merged in the current state of tupui/scipy@search_theme
  3. update a couple packages in my scipy-dev environment including this theme (mamba remove sphinx-panels; mamba upgrade sphinx meson pydata-sphinx-theme) so I can build with sphinx 5 and theme 0.13.1
  4. housekeeping: git submodule update --init; meson setup /opt/scipy/build --wipe
  5. python dev.py build -j 12
  6. time python dev.py doc -j 12

result: 5 autodoc-related warnings...

reading sources... [100%] reference/special.cython_special                                                           
WARNING: autodoc: failed to import property 'Delaunay.vertices' from module 'scipy.spatial'; the following exception was raised:
Traceback (most recent call last):
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/util/inspect.py", line 376, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: type object 'Delaunay' has no attribute 'vertices'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/importer.py", line 98, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/__init__.py", line 306, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/__init__.py", line 2804, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/util/inspect.py", line 392, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: vertices

WARNING: autodoc: failed to import function 'directionalmean' from module 'scipy.stats'; the following exception was raised:
Traceback (most recent call last):
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/util/inspect.py", line 376, in safe_getattr
    return getattr(obj, name, *defargs)
AttributeError: module 'scipy.stats' has no attribute 'directionalmean'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/importer.py", line 98, in import_object
    obj = attrgetter(obj, mangled_name)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/__init__.py", line 306, in get_attr
    return autodoc_attrgetter(self.env.app, obj, name, *defargs)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/ext/autodoc/__init__.py", line 2804, in autodoc_attrgetter
    return safe_getattr(obj, name, *defargs)
  File "/opt/miniforge3/envs/scipy-dev/lib/python3.10/site-packages/sphinx/util/inspect.py", line 392, in safe_getattr
    raise AttributeError(name) from exc
AttributeError: directionalmean

looking for now-outdated files... none found
pickling environment... done
checking consistency... /opt/scipy/doc/source/reference/generated/scipy.odr.odr.rst: WARNING: document isn't included in any toctree
/opt/scipy/doc/source/reference/generated/scipy.signal.czt.rst: WARNING: document isn't included in any toctree
/opt/scipy/doc/source/reference/generated/scipy.stats.directionalmean.rst: WARNING: document isn't included in any toctree
done
preparing documents... done

@tupui are you also seeing those autodoc warnings?

As for build time, user + sys is showing ~29 minutes, which is well below the ~1hr mark you're seeing on your CIs:

real	2m31.096s
user	27m33.441s
sys	1m29.504s

Here's my environment:

$ mamba list
# packages in environment at /opt/miniforge3/envs/scipy-dev:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
accessible-pygments       0.0.3              pyhd8ed1ab_0    conda-forge
alabaster                 0.7.12                     py_0    conda-forge
alsa-lib                  1.2.3.2              h166bdaf_0    conda-forge
appdirs                   1.4.4              pyh9f0ad1d_0    conda-forge
asttokens                 2.0.8              pyhd8ed1ab_0    conda-forge
asv                       0.4.2                    pypi_0    pypi
attrs                     22.1.0             pyh71513ae_1    conda-forge
babel                     2.10.3             pyhd8ed1ab_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                        py_2    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
beautifulsoup4            4.11.1             pyha770c72_0    conda-forge
beniget                   0.4.1              pyhd8ed1ab_0    conda-forge
binutils                  2.36.1               hdd6e379_2    conda-forge
binutils_impl_linux-64    2.36.1               h193b22a_2    conda-forge
binutils_linux-64         2.36                hf3e587d_10    conda-forge
brotli                    1.0.9                h166bdaf_7    conda-forge
brotli-bin                1.0.9                h166bdaf_7    conda-forge
brotlipy                  0.7.0                    pypi_0    pypi
bzip2                     1.0.8                h7f98852_4    conda-forge
c-compiler                1.4.2                h166bdaf_0    conda-forge
ca-certificates           2022.12.7            ha878542_0    conda-forge
certifi                   2022.12.7          pyhd8ed1ab_0    conda-forge
cffi                      1.15.1                   pypi_0    pypi
chardet                   5.0.0                    pypi_0    pypi
charset-normalizer        2.1.0              pyhd8ed1ab_0    conda-forge
click                     8.1.3                    pypi_0    pypi
cloudpickle               2.1.0              pyhd8ed1ab_0    conda-forge
colorama                  0.4.5              pyhd8ed1ab_0    conda-forge
commonmark                0.9.1                      py_0    conda-forge
compilers                 1.4.2                ha770c72_0    conda-forge
conda                     4.14.0                   pypi_0    pypi
conda-build               3.22.0                   pypi_0    pypi
conda-package-handling    1.8.1                    pypi_0    pypi
coverage                  6.4.4                    pypi_0    pypi
cryptography              39.0.2                   pypi_0    pypi
cxx-compiler              1.4.2                h924138e_0    conda-forge
cycler                    0.11.0             pyhd8ed1ab_0    conda-forge
cython                    0.29.32                  pypi_0    pypi
dataclasses               0.8                pyhc8e2a94_3    conda-forge
dbus                      1.13.6               h5008d03_3    conda-forge
decorator                 5.1.1              pyhd8ed1ab_0    conda-forge
docutils                  0.17.1                   pypi_0    pypi
doit                      0.36.0             pyhd8ed1ab_0    conda-forge
execnet                   1.9.0              pyhd8ed1ab_0    conda-forge
executing                 0.10.0             pyhd8ed1ab_0    conda-forge
expat                     2.4.8                h27087fc_0    conda-forge
filelock                  3.8.0              pyhd8ed1ab_0    conda-forge
flake8                    5.0.4              pyhd8ed1ab_0    conda-forge
font-ttf-dejavu-sans-mono 2.37                 hab24e00_0    conda-forge
font-ttf-inconsolata      3.000                h77eed37_0    conda-forge
font-ttf-source-code-pro  2.038                h77eed37_0    conda-forge
font-ttf-ubuntu           0.83                 hab24e00_0    conda-forge
fontconfig                2.14.0               h8e229c2_0    conda-forge
fonts-conda-ecosystem     1                             0    conda-forge
fonts-conda-forge         1                             0    conda-forge
fonttools                 4.36.0                   pypi_0    pypi
fortran-compiler          1.4.2                h2a4ca65_0    conda-forge
freetype                  2.12.1               hca18f0e_0    conda-forge
future                    0.18.2                   pypi_0    pypi
gast                      0.5.3              pyhd8ed1ab_0    conda-forge
gcc                       10.4.0              hb92f740_10    conda-forge
gcc_impl_linux-64         10.4.0              h7ee1905_16    conda-forge
gcc_linux-64              10.4.0              h9215b83_10    conda-forge
gettext                   0.19.8.1          h73d1719_1008    conda-forge
gfortran                  10.4.0              h0c96582_10    conda-forge
gfortran_impl_linux-64    10.4.0              h44b2e72_16    conda-forge
gfortran_linux-64         10.4.0              h69d5af5_10    conda-forge
glib                      2.72.1               h6239696_0    conda-forge
glib-tools                2.72.1               h6239696_0    conda-forge
glob2                     0.7                        py_0    conda-forge
gmp                       6.2.1                h58526e2_0    conda-forge
gmpy2                     2.1.2                    pypi_0    pypi
gst-plugins-base          1.20.2               hcf0ee16_0    conda-forge
gstreamer                 1.20.3               hd4edc92_0    conda-forge
gxx                       10.4.0              hb92f740_10    conda-forge
gxx_impl_linux-64         10.4.0              h7ee1905_16    conda-forge
gxx_linux-64              10.4.0              h6e491c6_10    conda-forge
icu                       69.1                 h9c3ff4c_0    conda-forge
idna                      3.3                pyhd8ed1ab_0    conda-forge
imagesize                 1.4.1              pyhd8ed1ab_0    conda-forge
importlib-metadata        4.11.4                   pypi_0    pypi
iniconfig                 1.1.1              pyh9f0ad1d_0    conda-forge
ipython                   8.4.0                    pypi_0    pypi
jbig                      2.1               h7f98852_2003    conda-forge
jedi                      0.18.1                   pypi_0    pypi
jinja2                    3.1.2              pyhd8ed1ab_1    conda-forge
jpeg                      9e                   h166bdaf_2    conda-forge
kernel-headers_linux-64   2.6.32              he073ed8_15    conda-forge
keyutils                  1.6.1                h166bdaf_0    conda-forge
kiwisolver                1.4.4                    pypi_0    pypi
krb5                      1.20.1               h81ceb04_0    conda-forge
lcms2                     2.12                 hddcbb42_0    conda-forge
ld_impl_linux-64          2.36.1               hea4e1c9_2    conda-forge
lerc                      4.0.0                h27087fc_0    conda-forge
libarchive                3.5.2                hed592e5_1    conda-forge
libarchive-c              4.0                      pypi_0    pypi
libblas                   3.9.0           16_linux64_openblas    conda-forge
libbrotlicommon           1.0.9                h166bdaf_7    conda-forge
libbrotlidec              1.0.9                h166bdaf_7    conda-forge
libbrotlienc              1.0.9                h166bdaf_7    conda-forge
libcblas                  3.9.0           16_linux64_openblas    conda-forge
libclang                  13.0.1          default_hc23dcda_0    conda-forge
libdeflate                1.13                 h166bdaf_0    conda-forge
libedit                   3.1.20191231         he28a2e2_2    conda-forge
libevent                  2.1.10               h28343ad_4    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc-devel_linux-64     10.4.0              h74af60c_16    conda-forge
libgcc-ng                 12.1.0              h8d9b700_16    conda-forge
libgfortran-ng            12.1.0              h69a702a_16    conda-forge
libgfortran5              12.1.0              hdcd56e2_16    conda-forge
libglib                   2.72.1               h2d90d5f_0    conda-forge
libgomp                   12.1.0              h8d9b700_16    conda-forge
libiconv                  1.16                 h516909a_0    conda-forge
liblapack                 3.9.0           16_linux64_openblas    conda-forge
liblief                   0.12.1               h27087fc_0    conda-forge
libllvm11                 11.1.0               hf817b99_3    conda-forge
libllvm13                 13.0.1               hf817b99_2    conda-forge
libnsl                    2.0.0                h7f98852_0    conda-forge
libogg                    1.3.4                h7f98852_1    conda-forge
libopenblas               0.3.21          pthreads_h78a6416_1    conda-forge
libopus                   1.3.1                h7f98852_1    conda-forge
libpng                    1.6.37               h753d276_4    conda-forge
libpq                     14.5                 hb675445_5    conda-forge
libsanitizer              10.4.0              hde28e3b_16    conda-forge
libsqlite                 3.39.2               h753d276_1    conda-forge
libstdcxx-devel_linux-64  10.4.0              h74af60c_16    conda-forge
libstdcxx-ng              12.1.0              ha89aaad_16    conda-forge
libtiff                   4.4.0                h0e0dad5_3    conda-forge
libuuid                   2.32.1            h7f98852_1000    conda-forge
libvorbis                 1.3.7                h9c3ff4c_0    conda-forge
libwebp-base              1.2.4                h166bdaf_0    conda-forge
libxcb                    1.13              h7f98852_1004    conda-forge
libxkbcommon              1.0.3                he3ba5ed_0    conda-forge
libxml2                   2.9.12               h885dcf4_1    conda-forge
libzlib                   1.2.13               h166bdaf_4    conda-forge
lz4-c                     1.9.3                h9c3ff4c_1    conda-forge
lzo                       2.10              h516909a_1000    conda-forge
markupsafe                2.1.1                    pypi_0    pypi
matplotlib                3.5.3                    pypi_0    pypi
matplotlib-base           3.5.3           py310h5701ce4_1    conda-forge
matplotlib-inline         0.1.6              pyhd8ed1ab_0    conda-forge
mccabe                    0.7.0              pyhd8ed1ab_0    conda-forge
meson                     1.0.1              pyhd8ed1ab_0    conda-forge
meson-python              0.8.1              pyh191b570_0    conda-forge
more-itertools            8.14.0             pyhd8ed1ab_0    conda-forge
mpc                       1.2.1                h9f54685_0    conda-forge
mpfr                      4.1.0                h9202a9a_1    conda-forge
mpmath                    1.2.1              pyhd8ed1ab_0    conda-forge
munkres                   1.1.4              pyh9f0ad1d_0    conda-forge
mypy                      0.971                    pypi_0    pypi
mypy-extensions           0.4.3                    pypi_0    pypi
mypy_extensions           0.4.3           py310hff52083_5    conda-forge
mysql-common              8.0.32               ha901b37_0    conda-forge
mysql-libs                8.0.32               hd7da12d_0    conda-forge
ncurses                   6.3                  h27087fc_1    conda-forge
ninja                     1.11.0               h924138e_0    conda-forge
nspr                      4.32                 h9c3ff4c_1    conda-forge
nss                       3.78                 h2350873_0    conda-forge
numpy                     1.23.2                   pypi_0    pypi
numpydoc                  1.4.0              pyhd8ed1ab_1    conda-forge
olefile                   0.46               pyh9f0ad1d_1    conda-forge
openblas                  0.3.21          pthreads_h320a7e8_1    conda-forge
openjpeg                  2.5.0                h7d73246_1    conda-forge
openssl                   3.0.8                h0b41bf4_0    conda-forge
packaging                 21.3               pyhd8ed1ab_0    conda-forge
parso                     0.8.3              pyhd8ed1ab_0    conda-forge
patch                     2.7.6             h7f98852_1002    conda-forge
patchelf                  0.15.0               h58526e2_0    conda-forge
pcre                      8.45                 h9c3ff4c_0    conda-forge
pexpect                   4.8.0              pyh9f0ad1d_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pillow                    9.2.0                    pypi_0    pypi
pip                       22.2.2             pyhd8ed1ab_0    conda-forge
pkg-config                0.29.2            h36c2ea0_1008    conda-forge
pkginfo                   1.8.3              pyhd8ed1ab_0    conda-forge
pluggy                    1.0.0                    pypi_0    pypi
ply                       3.11                       py_1    conda-forge
pooch                     1.6.0              pyhd8ed1ab_0    conda-forge
prompt-toolkit            3.0.30             pyha770c72_0    conda-forge
psutil                    5.9.1                    pypi_0    pypi
pthread-stubs             0.4               h36c2ea0_1001    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
pure_eval                 0.2.2              pyhd8ed1ab_0    conda-forge
py                        1.11.0             pyh6c4a22f_0    conda-forge
py-lief                   0.12.1          py310hd8f1fbe_0    conda-forge
pybind11                  2.10.0                   pypi_0    pypi
pybind11-global           2.10.0                   pypi_0    pypi
pycodestyle               2.9.1              pyhd8ed1ab_0    conda-forge
pycosat                   0.6.3                    pypi_0    pypi
pycparser                 2.21               pyhd8ed1ab_0    conda-forge
pydata-sphinx-theme       0.13.1             pyhd8ed1ab_0    conda-forge
pydevtool                 0.3.0              pyhd8ed1ab_0    conda-forge
pyflakes                  2.5.0              pyhd8ed1ab_0    conda-forge
pygments                  2.13.0             pyhd8ed1ab_0    conda-forge
pyopenssl                 22.0.0             pyhd8ed1ab_0    conda-forge
pyparsing                 3.0.9              pyhd8ed1ab_0    conda-forge
pyproject-metadata        0.6.1              pyhd8ed1ab_0    conda-forge
pyqt                      5.12.3          py310hff52083_8    conda-forge
pyqt-impl                 5.12.3          py310h1f8e252_8    conda-forge
pyqt5                     5.12.3                   pypi_0    pypi
pyqt5-sip                 4.19.18                  pypi_0    pypi
pyqtchart                 5.12                     pypi_0    pypi
pyqtwebengine             5.12.1                   pypi_0    pypi
pysocks                   1.7.1                    pypi_0    pypi
pytest                    7.1.2                    pypi_0    pypi
pytest-cov                3.0.0              pyhd8ed1ab_0    conda-forge
pytest-forked             1.4.0              pyhd8ed1ab_0    conda-forge
pytest-timeout            2.1.0              pyhd8ed1ab_0    conda-forge
pytest-xdist              2.5.0              pyhd8ed1ab_0    conda-forge
python                    3.10.5          ha86cf86_0_cpython    conda-forge
python-dateutil           2.8.2              pyhd8ed1ab_0    conda-forge
python-libarchive-c       4.0             py310hff52083_1    conda-forge
python_abi                3.10                    2_cp310    conda-forge
pythran                   0.11.0                   pypi_0    pypi
pytz                      2022.2.1           pyhd8ed1ab_0    conda-forge
pyyaml                    6.0                      pypi_0    pypi
qt                        5.12.9               h1304e3e_6    conda-forge
readline                  8.1.2                h0f457ee_0    conda-forge
requests                  2.28.1             pyhd8ed1ab_0    conda-forge
rich                      12.5.1             pyhd8ed1ab_0    conda-forge
rich-click                1.5.2              pyhd8ed1ab_0    conda-forge
ripgrep                   13.0.0               h2f28480_2    conda-forge
ruamel-yaml-conda         0.15.80                  pypi_0    pypi
ruamel_yaml               0.15.80         py310h5764c6d_1007    conda-forge
setuptools                59.8.0                   pypi_0    pypi
six                       1.16.0             pyh6c4a22f_0    conda-forge
snowballstemmer           2.2.0              pyhd8ed1ab_0    conda-forge
soupsieve                 2.3.2.post1        pyhd8ed1ab_0    conda-forge
sphinx                    5.3.0              pyhd8ed1ab_0    conda-forge
sphinx-design             0.2.0              pyhd8ed1ab_1    conda-forge
sphinxcontrib-applehelp   1.0.2                      py_0    conda-forge
sphinxcontrib-devhelp     1.0.2                      py_0    conda-forge
sphinxcontrib-htmlhelp    2.0.0              pyhd8ed1ab_0    conda-forge
sphinxcontrib-jsmath      1.0.1                      py_0    conda-forge
sphinxcontrib-qthelp      1.0.3                      py_0    conda-forge
sphinxcontrib-serializinghtml 1.1.5              pyhd8ed1ab_2    conda-forge
sqlite                    3.39.2               h4ff8645_1    conda-forge
stack_data                0.4.0              pyhd8ed1ab_0    conda-forge
sysroot_linux-64          2.12                he073ed8_15    conda-forge
threadpoolctl             3.1.0              pyh8a188c0_0    conda-forge
tk                        8.6.12               h27826a3_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tomli                     2.0.1              pyhd8ed1ab_0    conda-forge
toolz                     0.12.0             pyhd8ed1ab_0    conda-forge
tornado                   6.2                      pypi_0    pypi
tqdm                      4.64.0             pyhd8ed1ab_0    conda-forge
traitlets                 5.3.0              pyhd8ed1ab_0    conda-forge
typing-extensions         4.3.0                hd8ed1ab_0    conda-forge
typing_extensions         4.3.0              pyha770c72_0    conda-forge
tzdata                    2022c                h191b570_0    conda-forge
unicodedata2              14.0.0                   pypi_0    pypi
urllib3                   1.26.11            pyhd8ed1ab_0    conda-forge
wcwidth                   0.2.5              pyh9f0ad1d_2    conda-forge
wheel                     0.37.1             pyhd8ed1ab_0    conda-forge
xorg-libxau               1.0.9                h7f98852_0    conda-forge
xorg-libxdmcp             1.1.3                h7f98852_0    conda-forge
xsimd                     8.0.5                h4bd325d_0    conda-forge
xz                        5.2.6                h166bdaf_0    conda-forge
yaml                      0.2.5                h7f98852_2    conda-forge
zipp                      3.8.1              pyhd8ed1ab_0    conda-forge
zlib                      1.2.13               h166bdaf_4    conda-forge
zstd                      1.5.2                h6239696_4    conda-forge

So as a SciPy outsider this seems like a wontfix:worksforme (except for the autodoc warnings, which I don't know whether those are expected or not / affecting timings or not) and I'll need your help figuring out what is different between your setup and mine such that you're seeing ~2x build times. The first thing I'd check is that your search_theme branch is 33 commits behind scipy@main whereas I did my test by merging those changes on top of current main, so maybe something has changed in the interim that affected doc build times, that you're not seeing in the CIs of your open PR?

@tupui
Copy link
Contributor Author

tupui commented Mar 7, 2023

Thank you @drammock for trying this out.

Discord? Whatever you said on Discord was in a server that we (or at least I) am not a member of. Please don't expect us to monitor Scipy's internal communication channels (even if they're public).

I was directly replying to Chris as we re-started this conversation on the Discord of Scientific Python.

@tupui are you also seeing those autodoc warnings?

I don't but we often have some discrepancy here between a local setup and CI. Not really a concern usually.

As for build time, user + sys is showing ~29 minutes, which is well below the ~1hr mark you're seeing on your CIs:

You are comparing -j 12 on a local machine with -j 2 on a share machine on the cloud...

Since you got it building, you can now more easily verify this by using main and the version 0.9 of the theme. You should see the difference (as IIRC you did see when we first discuss on the linked PR.)

So as a SciPy outsider this seems like a wontfix:worksforme (except for the autodoc warnings, which I don't know whether those are expected or not / affecting timings or not) and I'll need your help figuring out what is different between your setup and mine such that you're seeing ~2x build times. The first thing I'd check is that your search_theme branch is 33 commits behind scipy@main whereas I did my test by merging those changes on top of current main, so maybe something has changed in the interim that affected doc build times, that you're not seeing in the CIs of your open PR?

Merging scipy@main is not important here.

@tupui
Copy link
Contributor Author

tupui commented Mar 7, 2023

@drammock here are some benchmarks I just did. The env is exactly the same for both, I only changed the theme's version.

Using 0.9 (scipy@main)

python dev.py doc -j 8  831.53s user 61.66s system 563% cpu 2:38.64 total

Using 0.13.1 (my branch and I merged scipy@main)

python dev.py doc -j 8  1965.03s user 254.58s system 556% cpu 6:38.77 total

(In case that could indicate anything: the writing log of Sphinx are slightly slower, but most of the time is spend after that when nothing is printed.)

@drammock
Copy link
Collaborator

drammock commented Mar 7, 2023

You are comparing -j 12 on a local machine with -j 2 on a share machine on the cloud...

I think that difference is not relevant unless comparing real. user + sys pools execution time across all used threads. Note that real in my results was 2.5 minutes vs 29 minutes for user + sys.

I'll see what else I can do when I can find time. Meanwhile please post your env. Differences in version of e.g. sphinx might matter here, so just saying "my env is the same across these benchmarks" doesn't help me figure out why my results differ from yours.

@tupui
Copy link
Contributor Author

tupui commented Mar 7, 2023

Sure, here is my env (results above are with only changing the version of the theme.) Throughout the course of this issue, I (and NumPy folks) could reproduce (locally and in CI) on multiple versions of Sphinx, numpydoc, Python, etc.

Conda Env
❯ mamba list
# packages in environment at /opt/homebrew/Caskroom/mambaforge/base/envs/scipy-dev:
#
# Name                    Version                   Build  Channel
accessible-pygments       0.0.3                    pypi_0    pypi
alabaster                 0.7.12                     py_0    conda-forge
anyio                     3.6.1           py310hbe9552e_0    conda-forge
appdirs                   1.4.4              pyh9f0ad1d_0    conda-forge
appnope                   0.1.3              pyhd8ed1ab_0    conda-forge
argon2-cffi               21.3.0             pyhd8ed1ab_0    conda-forge
argon2-cffi-bindings      21.2.0          py310hf8d0d8f_2    conda-forge
asttokens                 2.0.5              pyhd8ed1ab_0    conda-forge
asv                       0.4.2           py310h1b49c16_3    conda-forge
attrs                     21.4.0             pyhd8ed1ab_0    conda-forge
babel                     2.10.1             pyhd8ed1ab_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                        py_2    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
beautifulsoup4            4.11.1             pyha770c72_0    conda-forge
beniget                   0.4.1              pyhd8ed1ab_0    conda-forge
bleach                    5.0.0              pyhd8ed1ab_0    conda-forge
brotli                    1.0.9                h1c322ee_7    conda-forge
brotli-bin                1.0.9                h1c322ee_7    conda-forge
brotlipy                  0.7.0           py310hf8d0d8f_1004    conda-forge
bzip2                     1.0.8                h3422bc3_4    conda-forge
c-compiler                1.4.1                hccd94f0_0    conda-forge
ca-certificates           2022.12.7            h4653dfc_0    conda-forge
cctools                   973.0.1             h5dcd5d4_10    conda-forge
cctools_osx-arm64         973.0.1             h83ffe51_10    conda-forge
certifi                   2022.12.7          pyhd8ed1ab_0    conda-forge
cffi                      1.15.0          py310hf10583b_0    conda-forge
charset-normalizer        2.0.12             pyhd8ed1ab_0    conda-forge
clang                     12.0.1               hce30654_4    conda-forge
clang-12                  12.0.1          default_h2cfa9b4_4    conda-forge
clang_osx-arm64           12.0.1               hc0c6576_9    conda-forge
clangxx                   12.0.1          default_hf584372_4    conda-forge
clangxx_osx-arm64         12.0.1               hc2331a0_9    conda-forge
click                     8.1.3           py310hbe9552e_0    conda-forge
cloudpickle               2.1.0              pyhd8ed1ab_0    conda-forge
colorama                  0.4.4              pyh9f0ad1d_0    conda-forge
commonmark                0.9.1                      py_0    conda-forge
compiler-rt               12.0.1               h94c6b0c_0    conda-forge
compiler-rt_osx-arm64     12.0.1               h44bac85_0    conda-forge
compilers                 1.4.1                hce30654_0    conda-forge
contourpy                 1.0.7           py310h2887b22_0    conda-forge
coverage                  6.4.1           py310h02f21da_0    conda-forge
cryptography              38.0.4          py310hfc83b78_0    conda-forge
cxx-compiler              1.4.1                h3e96240_0    conda-forge
cycler                    0.11.0             pyhd8ed1ab_0    conda-forge
cython                    0.29.33         py310h0f1eb42_0    conda-forge
cython-lint               0.12.4             pyhd8ed1ab_0    conda-forge
dataclasses               0.8                pyhc8e2a94_3    conda-forge
debugpy                   1.6.0           py310h1105856_0    conda-forge
decorator                 5.1.1              pyhd8ed1ab_0    conda-forge
defusedxml                0.7.1              pyhd8ed1ab_0    conda-forge
docutils                  0.17.1          py310hbe9552e_2    conda-forge
doit                      0.36.0             pyhd8ed1ab_0    conda-forge
entrypoints               0.4                pyhd8ed1ab_0    conda-forge
execnet                   1.9.0              pyhd8ed1ab_0    conda-forge
executing                 0.8.3              pyhd8ed1ab_0    conda-forge
fftw                      3.3.10          nompi_h828537f_102    conda-forge
flake8                    4.0.1              pyhd8ed1ab_2    conda-forge
flit-core                 3.7.1              pyhd8ed1ab_0    conda-forge
fonttools                 4.33.3          py310h02f21da_0    conda-forge
fortran-compiler          1.4.1                haab47bd_0    conda-forge
freetype                  2.12.1               hd633e50_1    conda-forge
future                    0.18.2          py310hbe9552e_5    conda-forge
gast                      0.5.3              pyhd8ed1ab_0    conda-forge
gettext                   0.19.8.1          h049c9fb_1008    conda-forge
gfortran                  11.0.1.dev0         h40eb566_15    conda-forge
gfortran_impl_osx-arm64   11.0.1.dev0         hbce66ab_23    conda-forge
gfortran_osx-arm64        11.0.1.dev0         h57527a5_15    conda-forge
giflib                    5.2.1                h27ca646_2    conda-forge
gmp                       6.2.1                h9f76cd9_0    conda-forge
gmpy2                     2.1.2           py310h25f46c9_0    conda-forge
idna                      3.3                pyhd8ed1ab_0    conda-forge
imagesize                 1.3.0              pyhd8ed1ab_0    conda-forge
importlib-metadata        4.11.4          py310hbe9552e_0    conda-forge
importlib_metadata        4.11.4               hd8ed1ab_0    conda-forge
importlib_resources       5.7.1              pyhd8ed1ab_1    conda-forge
iniconfig                 1.1.1              pyh9f0ad1d_0    conda-forge
ipykernel                 6.13.1          py310hc469350_0    conda-forge
ipympl                    0.9.2              pyhd8ed1ab_0    conda-forge
ipython                   8.4.0           py310hbe9552e_0    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                8.0.2              pyhd8ed1ab_1    conda-forge
isl                       0.22.1               hb904e53_2    conda-forge
jedi                      0.18.1          py310hbe9552e_1    conda-forge
jinja2                    3.0.3              pyhd8ed1ab_0    conda-forge
joblib                    1.1.0              pyhd8ed1ab_0    conda-forge
jpeg                      9e                   h1c322ee_1    conda-forge
json5                     0.9.5              pyh9f0ad1d_0    conda-forge
jsonschema                4.6.0              pyhd8ed1ab_0    conda-forge
jupyter_client            7.3.4              pyhd8ed1ab_0    conda-forge
jupyter_core              4.10.0          py310hbe9552e_0    conda-forge
jupyter_server            1.16.0             pyhd8ed1ab_0    conda-forge
jupyterlab                3.4.3              pyhd8ed1ab_0    conda-forge
jupyterlab_pygments       0.2.2              pyhd8ed1ab_0    conda-forge
jupyterlab_server         2.14.0             pyhd8ed1ab_0    conda-forge
jupyterlab_widgets        3.0.3              pyhd8ed1ab_0    conda-forge
kiwisolver                1.4.2           py310hea002bf_1    conda-forge
lcms2                     2.12                 had6a04f_0    conda-forge
ld64                      609                 h8d6e053_10    conda-forge
ld64_osx-arm64            609                 h7c97014_10    conda-forge
lerc                      3.0                  hbdafb3b_0    conda-forge
libblas                   3.9.0           15_osxarm64_openblas    conda-forge
libbrotlicommon           1.0.9                h1c322ee_7    conda-forge
libbrotlidec              1.0.9                h1c322ee_7    conda-forge
libbrotlienc              1.0.9                h1c322ee_7    conda-forge
libcblas                  3.9.0           15_osxarm64_openblas    conda-forge
libclang-cpp12            12.0.1          default_h2cfa9b4_4    conda-forge
libcxx                    14.0.6               h2692d47_0    conda-forge
libdeflate                1.10                 h3422bc3_0    conda-forge
libffi                    3.4.2                h3422bc3_5    conda-forge
libgfortran               5.0.0.dev0      11_0_1_hf114ba7_23    conda-forge
libgfortran-devel_osx-arm64 11.0.1.dev0         hf114ba7_23    conda-forge
libgfortran5              11.0.1.dev0         hf114ba7_23    conda-forge
libglib                   2.70.2               h67e64d8_4    conda-forge
libiconv                  1.16                 h642e427_0    conda-forge
liblapack                 3.9.0           15_osxarm64_openblas    conda-forge
libllvm12                 12.0.1               h93073aa_2    conda-forge
libopenblas               0.3.20          openmp_h2209c59_0    conda-forge
libpng                    1.6.39               h76d750c_0    conda-forge
libsodium                 1.0.18               h27ca646_1    conda-forge
libsqlite                 3.39.4               h76d750c_0    conda-forge
libtiff                   4.4.0                h2810ee2_0    conda-forge
libwebp                   1.2.2                h0d20362_0    conda-forge
libwebp-base              1.2.2                h3422bc3_1    conda-forge
libxcb                    1.13              h9b22ae9_1004    conda-forge
libzlib                   1.2.13               h03a7124_4    conda-forge
line-profiler             4.0.2                    pypi_0    pypi
llvm-openmp               14.0.4               hd125106_0    conda-forge
llvm-tools                12.0.1               h93073aa_2    conda-forge
lz4-c                     1.9.3                hbdafb3b_1    conda-forge
markupsafe                2.1.1           py310hf8d0d8f_1    conda-forge
matplotlib                3.6.3           py310hb6292c7_0    conda-forge
matplotlib-base           3.6.3           py310h78c5c2f_0    conda-forge
matplotlib-inline         0.1.3              pyhd8ed1ab_0    conda-forge
mccabe                    0.6.1                      py_1    conda-forge
meson                     0.64.1             pyhd8ed1ab_0    conda-forge
meson-python              0.13.0.dev0              pypi_0    pypi
mistune                   0.8.4           py310he2143c4_1005    conda-forge
mpc                       1.2.1                h309154c_0    conda-forge
mpfr                      4.1.0                h6d7a090_1    conda-forge
mpmath                    1.2.1              pyhd8ed1ab_0    conda-forge
munkres                   1.1.4              pyh9f0ad1d_0    conda-forge
mypy                      1.0.0           py310h8e9501a_0    conda-forge
mypy_extensions           0.4.3           py310hbe9552e_5    conda-forge
nbclassic                 0.3.7              pyhd8ed1ab_0    conda-forge
nbclient                  0.5.13             pyhd8ed1ab_0    conda-forge
nbconvert                 6.4.5           py310hbe9552e_0    conda-forge
nbformat                  5.4.0              pyhd8ed1ab_0    conda-forge
ncurses                   6.3                  h07bb92c_1    conda-forge
nest-asyncio              1.5.5              pyhd8ed1ab_0    conda-forge
ninja                     1.11.0               hf86a087_0    conda-forge
notebook                  6.4.12             pyha770c72_0    conda-forge
notebook-shim             0.1.0              pyhd8ed1ab_0    conda-forge
numpy                     1.24.0.dev0+212.gc8dd91b63          pypi_0    pypi
numpydoc                  1.4.0              pyhd8ed1ab_1    conda-forge
openblas                  0.3.20          openmp_h745f6c2_0    conda-forge
openjpeg                  2.4.0                h062765e_1    conda-forge
openssl                   3.0.8                h03a7124_0    conda-forge
packaging                 21.3               pyhd8ed1ab_0    conda-forge
pandas                    1.4.2           py310ha6a5cd6_2    conda-forge
pandocfilters             1.5.0              pyhd8ed1ab_0    conda-forge
parso                     0.8.3              pyhd8ed1ab_0    conda-forge
patsy                     0.5.2              pyhd8ed1ab_0    conda-forge
pcre                      8.45                 hbdafb3b_0    conda-forge
pep621                    0.4.0              pyhd8ed1ab_0    conda-forge
pexpect                   4.8.0              pyh9f0ad1d_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pillow                    9.1.1           py310hc9df86f_1    conda-forge
pip                       22.1.2             pyhd8ed1ab_0    conda-forge
pkg-config                0.29.2            hab62308_1008    conda-forge
platformdirs              2.6.0              pyhd8ed1ab_0    conda-forge
pluggy                    1.0.0           py310hbe9552e_3    conda-forge
ply                       3.11                       py_1    conda-forge
pooch                     1.7.0              pyhd8ed1ab_0    conda-forge
prometheus_client         0.14.1             pyhd8ed1ab_0    conda-forge
prompt-toolkit            3.0.29             pyha770c72_0    conda-forge
psutil                    5.9.1           py310h02f21da_0    conda-forge
pthread-stubs             0.4               h27ca646_1001    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
pure_eval                 0.2.2              pyhd8ed1ab_0    conda-forge
py                        1.11.0             pyh6c4a22f_0    conda-forge
pybind11                  2.9.2           py310hea002bf_1    conda-forge
pybind11-global           2.9.2           py310hea002bf_1    conda-forge
pycodestyle               2.8.0              pyhd8ed1ab_0    conda-forge
pycparser                 2.21               pyhd8ed1ab_0    conda-forge
pydata-sphinx-theme       0.9.0                    pypi_0    pypi
pydevtool                 0.2.0              pyhd8ed1ab_0    conda-forge
pyfftw                    0.13.0          py310h674e598_2    conda-forge
pyflakes                  2.4.0              pyhd8ed1ab_0    conda-forge
pygments                  2.12.0             pyhd8ed1ab_0    conda-forge
pyopenssl                 22.0.0             pyhd8ed1ab_0    conda-forge
pyparsing                 3.0.9              pyhd8ed1ab_0    conda-forge
pyproject-metadata        0.6.1                    pypi_0    pypi
pyrsistent                0.18.1          py310hf8d0d8f_1    conda-forge
pysocks                   1.7.1           py310hbe9552e_5    conda-forge
pytest                    7.1.2           py310hbe9552e_0    conda-forge
pytest-cov                3.0.0              pyhd8ed1ab_0    conda-forge
pytest-forked             1.4.0              pyhd8ed1ab_0    conda-forge
pytest-timeout            2.1.0              pyhd8ed1ab_0    conda-forge
pytest-xdist              2.5.0              pyhd8ed1ab_0    conda-forge
python                    3.10.6          hae75cb6_0_cpython    conda-forge
python-dateutil           2.8.2              pyhd8ed1ab_0    conda-forge
python-fastjsonschema     2.15.3             pyhd8ed1ab_0    conda-forge
python_abi                3.10                    2_cp310    conda-forge
pythran                   0.11.0          py310h4566fd1_2    conda-forge
pytz                      2022.1             pyhd8ed1ab_0    conda-forge
pyyaml                    6.0             py310h8e9501a_5    conda-forge
pyzmq                     23.1.0          py310hede2015_0    conda-forge
readline                  8.1.2                h46ed386_0    conda-forge
requests                  2.27.1             pyhd8ed1ab_0    conda-forge
rich                      12.4.4             pyhd8ed1ab_0    conda-forge
rich-click                1.5.1              pyhd8ed1ab_0    conda-forge
ruff                      0.0.220         py310h7d3ac2c_0    conda-forge
scikit-learn              1.1.2           py310h3d7afdd_0    conda-forge
seaborn                   0.12.0               hd8ed1ab_0    conda-forge
seaborn-base              0.12.0             pyhd8ed1ab_0    conda-forge
send2trash                1.8.0              pyhd8ed1ab_0    conda-forge
setuptools                59.8.0          py310hbe9552e_1    conda-forge
sigtool                   0.1.3                h44b9a77_0    conda-forge
six                       1.16.0             pyh6c4a22f_0    conda-forge
sniffio                   1.2.0           py310hbe9552e_3    conda-forge
snowballstemmer           2.2.0              pyhd8ed1ab_0    conda-forge
soupsieve                 2.3.1              pyhd8ed1ab_0    conda-forge
sphinx                    5.1.0.dev20220615           dev_0    <develop>
sphinx-copybutton         0.5.0              pyhd8ed1ab_0    conda-forge
sphinx-design             0.2.0              pyhd8ed1ab_1    conda-forge
sphinx-tabs               3.3.1              pyhd8ed1ab_0    conda-forge
sphinxcontrib-applehelp   1.0.2                      py_0    conda-forge
sphinxcontrib-devhelp     1.0.2                      py_0    conda-forge
sphinxcontrib-htmlhelp    2.0.0              pyhd8ed1ab_0    conda-forge
sphinxcontrib-jsmath      1.0.1                      py_0    conda-forge
sphinxcontrib-qthelp      1.0.3                      py_0    conda-forge
sphinxcontrib-serializinghtml 1.1.5              pyhd8ed1ab_2    conda-forge
sqlite                    3.38.5               h40dfcc0_0    conda-forge
stack_data                0.2.0              pyhd8ed1ab_0    conda-forge
statsmodels               0.13.2          py310h611a7d1_0    conda-forge
tapi                      1100.0.11            he4954df_0    conda-forge
terminado                 0.15.0          py310hbe9552e_0    conda-forge
testpath                  0.6.0              pyhd8ed1ab_0    conda-forge
threadpoolctl             3.1.0              pyh8a188c0_0    conda-forge
tk                        8.6.12               he1e0b03_0    conda-forge
tokenize-rt               5.0.0              pyhd8ed1ab_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tomli                     2.0.1              pyhd8ed1ab_0    conda-forge
tornado                   6.1             py310hf8d0d8f_3    conda-forge
tqdm                      4.64.1             pyhd8ed1ab_0    conda-forge
traitlets                 5.2.2.post1        pyhd8ed1ab_0    conda-forge
types-psutil              5.9.5.6            pyhd8ed1ab_0    conda-forge
typing-extensions         4.3.0                hd8ed1ab_0    conda-forge
typing_extensions         4.3.0              pyha770c72_0    conda-forge
tzdata                    2022a                h191b570_0    conda-forge
unicodedata2              14.0.0          py310hf8d0d8f_1    conda-forge
urllib3                   1.26.9             pyhd8ed1ab_0    conda-forge
wcwidth                   0.2.5              pyh9f0ad1d_2    conda-forge
webencodings              0.5.1                      py_1    conda-forge
websocket-client          1.3.2              pyhd8ed1ab_0    conda-forge
wheel                     0.37.1             pyhd8ed1ab_0    conda-forge
widgetsnbextension        4.0.3              pyhd8ed1ab_0    conda-forge
xorg-libxau               1.0.9                h27ca646_0    conda-forge
xorg-libxdmcp             1.1.3                h27ca646_0    conda-forge
xsimd                     8.0.5                hc021e02_0    conda-forge
xz                        5.2.6                h57fd34a_0    conda-forge
yaml                      0.2.5                h3422bc3_2    conda-forge
zeromq                    4.3.4                hbdafb3b_1    conda-forge
zipp                      3.8.0              pyhd8ed1ab_0    conda-forge
zlib                      1.2.13               h03a7124_4    conda-forge
zstd                      1.5.2                hd705a24_1    conda-forge

@drammock
Copy link
Collaborator

drammock commented Mar 9, 2023

@tupui here are my results. I cloned my scipy-dev environment (which has version 0.13.1 of the theme) and the only thing I changed was downgrading the theme to version 0.9.0. Before running the doc build in each env, I ran python dev.py doc clean. The results are very very similar, and slightly faster for 0.13.1:

$ time python dev.py doc -j 6
real	7m45.241s
user	37m46.806s
sys	2m21.840s
$ mamba list pydata
# packages in environment at /opt/miniforge3/envs/spdev-pst9:
#
# Name                    Version                   Build  Channel
pydata-sphinx-theme       0.9.0              pyhd8ed1ab_1    conda-forge

this had 3 warnings: one from within scipy coming from scipy.ndimage._interpolation.rotate docstring, and 2 from the theme about undefined config values (secondary_sidebar_items and analytics)

/opt/scipy/build-install/lib/python3.10/site-packages/scipy/ndimage/_interpolation.py:docstring of scipy.ndimage._interpolation.rotate:103: WARNING: Exception occurred in plotting scipy-ndimage-rotate-1
 from /opt/scipy/doc/source/reference/generated/scipy.ndimage.rotate.rst:
Traceback (most recent call last):
  File "/opt/miniforge3/envs/spdev-pst9/lib/python3.10/site-packages/matplotlib/sphinxext/plot_directive.py", line 517, in _run_code
    exec(code, ns)
  File "<string>", line 14, in <module>
AttributeError: 'Figure' object has no attribute 'set_layout_engine'
[...]
WARNING: unsupported theme option 'secondary_sidebar_items' given
WARNING: unsupported theme option 'analytics' given

With 0.13.1 (below) there is just the one warning from within scipy, and the timings are basically the same:

$ time python dev.py doc -j 6
real	7m20.661s
user	35m39.990s
sys	2m20.807s
$ mamba list pydata
# packages in environment at /opt/miniforge3/envs/scipy-dev:
#
# Name                    Version                   Build  Channel
pydata-sphinx-theme       0.13.1             pyhd8ed1ab_0    conda-forge

note: the build time in my earlier comment from 2 days ago is not accurate: I was forgetting to do python dev.py doc clean beforehand

@tupui
Copy link
Contributor Author

tupui commented Mar 9, 2023

Very strange as it does not match the CI and my runs. I will try to reproduce your timing tomorrow from scratch.

I am not sure about your cleaning. There is a clean in the makefile but I am not sure dev.py is passing that to the make command.

@drammock
Copy link
Collaborator

drammock commented Mar 9, 2023

Well, it looks like it's doing what you'd expect:

$ python dev.py doc clean
💻  ninja -C /opt/scipy/build
ninja: Entering directory `/opt/scipy/build'
[4/4] Generating scipy/generate-version with a custom command
Build OK
💻  meson install -C build --only-changed
Installing, see meson-install.log...
Installation OK
rm -rf build/* source/reference/generated  <----- THIS LOOKS RIGHT, DOESN'T IT?

...although to be honest I was surprised that python dev.py --help didn't list a clean or doc clean command. I found it through python dev.py doc --list-targets

@tupui
Copy link
Contributor Author

tupui commented Mar 10, 2023

Ok yes I confirm the cleaning part. This should be documented I will see to update the doc.


I managed to reproduce your timings. Here is what is happening.

Using the PR with 0.9 I get:

python dev.py doc -j 8  2174.72s user 452.91s system 486% cpu 8:59.65 total

This PR uses "navigation_depth": 1, and remove the sidebar-nav-bs.html containing the following:

<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
  <div class="bd-toc-item active">
    {% if pagename.startswith("reference") %}
    {{ generate_nav_html("sidebar", maxdepth=1, collapse=True, includehidden=True, titles_only=True) }}
    {% else %}
    {{ generate_nav_html("sidebar", maxdepth=2, collapse=True, includehidden=True, titles_only=True) }}
    {% endif %}
  </div>
</nav>

This change was suggested by Chris and he approved the PR so I did not question it further.

Adding back sidebar-nav-bs.html the new timing is better:

python dev.py doc -j 8  856.55s user 75.17s system 542% cpu 2:51.73 total

Now if I update the theme to 0.13.1 the timings are as follow:

  • with sidebar-nav-bs.html (generate_nav_html replaced with generate_toctree_html)

    python dev.py doc -j 8  2252.97s user 438.79s system 491% cpu 9:08.03 total
    
  • and without the file

    python dev.py doc -j 8  2012.00s user 294.58s system 491% cpu 7:49.00 total
    

Finally, staying on this configuration and removing the autosummary templates I get (this will make lot of warnings because we rely on them, but the doc still builds):

python dev.py doc -j 8  1079.19s user 68.94s system 538% cpu 3:33.38 total

(Note about the warning you see. It's due to a change introduced in Matplotlib 3.6)

@drammock
Copy link
Collaborator

I managed to reproduce your timings.

did you? Mine were:

If I'm reading you correctly, yours were:

  • 36:15 with theme 0.9.0 on your PR
  • 14:17 with theme 0.9.0 on your PR plus adding back the sidebar-nav-bs template
  • 37:33 with theme 0.13.1 on your PR plus adding back the sidebar-nav-bs template
  • 33:32 with theme 0.13.1 on your PR (without sidebar-nav-bs)
  • 17:59 with theme 0.13.1 on your PR (without sidebar-nav-bs and without autosummary templates)

so you're not testing the same thing as me, which makes it hard to say whether you've reproduced my timings or not.

The next things I'll try (unless you suggest something else) are:

  1. look more carefully at your PR
  2. open my own PR into Scipy so that I can more carefully scrutinize exactly what is getting installed by the CIs when we ask it to install 0.9 vs 0.13.1 theme. I'm assuming Scipy will have some commit flags like skip-azp or similar, could you please tell me which ones I should use in order to only run the doc build and not waste server cycles on other CI jobs like running tests, etc.

It will likely be mid-next-week before I can get back to this.

@tupui
Copy link
Contributor Author

tupui commented Mar 14, 2023

did you? Mine were...

Yes, and the listing you posted is correctly highlighting the hierarchy of timings (the 2x and roughly back to performances from 0.9).

The discrepancy between your numbers and mine are not really relevant IMO as I would not say timing is very consistent.

@12rambau
Copy link
Collaborator

@tupui I come back to this issue as it's really enoying me. I tried in all the libs I'm working on that are using autosummary+ templates and I'm not able to reproduce your issue (I was expecting to see the same x2). I agree with @drammock there is something in your templates that is not behaving as expected.

In a related PR you shared the following code (#878 (comment)):

{{ fullname }}
{{ underline }}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
   :no-members:
   :no-inherited-members:
   :no-special-members:

  {% block methods %}
   .. HACK -- the point here is that we don't want this to appear in the output, but the autosummary should still generate the pages.
      .. autosummary::
         :toctree:
      {% for item in all_methods %}
         {%- if not item.startswith('_') or item in ['__call__', '__mul__', '__getitem__', '__len__'] %}
         {{ name }}.{{ item }}
         {%- endif -%}
      {%- endfor %}
      {% for item in inherited_members %}
         {%- if item in ['__call__', '__mul__', '__getitem__', '__len__'] %}
         {{ name }}.{{ item }}
         {%- endif -%}
      {%- endfor %}
  {% endblock %}

  {% block attributes %}
  {% if attributes %}
   .. HACK -- the point here is that we don't want this to appear in the output, but the autosummary should still generate the pages.
      .. autosummary::
         :toctree:
      {% for item in all_attributes %}
         {%- if not item.startswith('_') %}
         {{ name }}.{{ item }}
         {%- endif -%}
      {%- endfor %}
  {% endif %}
  {% endblock %}

Are you still using the same and could you share where it is ? (I want to see the diff with the normal one)

@tupui
Copy link
Contributor Author

tupui commented May 22, 2023

Thank you for having a look @12rambau! I really appreciate the help here. You can find everything here: doc/source/_templates

I am happy to hop in a call or anything if that can help.

@drammock
Copy link
Collaborator

@tupui we can also look at this together in person sometime this week :)

@tupui
Copy link
Contributor Author

tupui commented May 22, 2023

Definitely! 😃

@12rambau
Copy link
Collaborator

You guys can meet in personn ? I'm jealous ;-)

@tupui
Copy link
Contributor Author

tupui commented May 23, 2023

Yes we are at a Scientific Python summit :) https://scientific-python.org/summits/developer/2023/

@12rambau
Copy link
Collaborator

12rambau commented May 23, 2023

ok small insight here:

  1. the way scipy API documentation is build is far from vanilla. There are _toctree command in the init.py files + specific templates for every type of inputs (methods, attibutes, class). It will take time to understand exactly what is happening there.
  2. I think the templates are not "the culprit". You splitted the classes into multiple files which increase the number of pages (i.e. the number of build navigations). I'm pretty sure a v0.9 build without template will be even faster than your benchmark.
  3. thanks to @drammock the change that make the build time explode is well identified: ENH: Make search field an overlay with button click #744. now what I need to understand is what this PR changed in your doc that didn't influenced more vanilla documentations.

One of my guess is that these toctree living in the python files were ignored by sphinx and are now taken into account when building the nav, making the build time explode. I need to continue investigate.

@12rambau
Copy link
Collaborator

12rambau commented May 23, 2023

@tupui can we chat somewhere else than in the issue tracker ? I don't want to flood others with my questions

@tupui
Copy link
Contributor Author

tupui commented May 23, 2023

@12rambau I sent you an email, thanks 😃

@javabster
Copy link

hi folks! Just wanted to hop in here and mention that we have been facing a very similar issue with our project. We don't use the pydata sphinx theme, we have our own qiskit-sphinx-theme that uses furo and have been going back and forth with the same problem for the last few weeks. The fact that we're both experiencing this might indicate this is a performance issue with sphinx itself 🤔

So far we've been experimenting with a few different solutions (at least for the short term), sharing the issue here in case you find it helpful: Qiskit/qiskit_sphinx_theme#328

@tupui
Copy link
Contributor Author

tupui commented Jul 20, 2023

Thank you @javabster! I am happy to read that we are not the only one 😅

From what I read in the linked issue, you seem to also have problems with the sidebar. That might be linked as I could also experiment there and saw large performance drop playing with that scipy/scipy#18604

@Eric-Arellano
Copy link

Eric-Arellano commented Jul 20, 2023

To recap our plan for qiskit-sphinx-theme, we are reorganizing our API docs to no longer have dedicated HTML pages for each method and each function. That makes the left sidebar much smaller, avoiding the slowdown. You do that by setting up autosummary templates like this: https://github.com/Qiskit/qiskit_sphinx_theme/tree/main/example_docs/docs/_templates/autosummary

That should get build times and HTML page sizes "acceptable enough" for prod builds.

For dev builds (e.g. CI), we will use sphinx-remove-toctrees to remove all stubs/ from the ToC. It results in a much worse UX, but it's a dev build, so it's not a huge deal. This is possible by reading in an environment variable in conf.py with os.environ. This workaround will keep the build fast enough for local iteration on the docs.

@tupui
Copy link
Contributor Author

tupui commented Jul 20, 2023

Interesting 👍 thank you for sharing that.

@dstansby
Copy link
Contributor

dstansby commented Nov 21, 2023

Hi all, we've been seing the same issue over at sunpy. I've done some profiling, and tracked the slowdown to these lines:

# If this is the page TOC, check if it is empty and remove it if so
def _remove_empty_templates(tname):
# These templates take too long to render, so skip them.
# They should never be empty anyway.
SKIP_EMPTY_TEMPLATE_CHECKS = ["sidebar-nav-bs.html", "navbar-nav.html"]
if not any(tname.endswith(temp) for temp in SKIP_EMPTY_TEMPLATE_CHECKS):
# Render the template and see if it is totally empty
rendered = app.builder.templates.render(tname, context)
if len(rendered.strip()) == 0:
return False
return True

Screenshot 2023-11-21 at 09 31 21

What seems to be happening is any custom templates are being rendered for every page, just for the purpose of checking if they're empty. For sunpy, as can be seen above in the profiling graph, this almost doubles the total build time. If we switch to the vanilla pydata_sphinx_theme the repeated calls to _remove_empty_templates() either don't occur or happen very fast.

So it seems like the way to approach this is see if there's a way to speed up _remove_empty_templates()?

@drammock
Copy link
Collaborator

Thank you @dstansby for the info! I'd hoped to revisit this last week (but ran out of time) and now I'm on holiday, but will pick up the baton in about a week when I'm back at my desk

@drammock
Copy link
Collaborator

I tried a naive attempt at speeding up the SciPy doc build (simply commenting out the line that calls _remove_empty_templates) and it had no noticable effect on build time 😞

@dstansby can you share how exactly you set up the profiling? Decorating setup(app) with @profile yielded an empty .lprof file when I ran kernprof -lv dev.py doc (maybe because of how the SciPy doc build is wrapped by dev.py?)

@dstansby
Copy link
Contributor

dstansby commented Dec 13, 2023

I did something like python -m cProfile -m sphinx . _build -o output.prof and then snakeviz output.prof for the visualisation.

@dstansby
Copy link
Contributor

And FWIW the slow code seems to have come in via #1115

@drammock
Copy link
Collaborator

drammock commented Dec 18, 2023

(lack of) progress report: for the scipy docs, there is almost no difference in build time between running with or without _remove_empty_templates(). Both land at about 33:45 (single-threaded build). Only difference was whether this line was commented out or not:

context[section] = list(filter(_remove_empty_templates, context[section]))

(I confirmed in snakeviz that _remove_empty_templates was simply not present for one build, and present --- but not taking much time --- for the other one). So it seems SunPy's slowdowns may be happening for a different reason than SciPy's.

@12rambau
Copy link
Collaborator

12rambau commented Jan 3, 2024

I'm reopening the issue until @tupui confirms with v0.15.0rc0 that this fix is effectively solving the scipy issue in their CI

@12rambau 12rambau reopened this Jan 3, 2024
@tupui
Copy link
Contributor Author

tupui commented Jan 3, 2024

I will do that today and let you know 😃

@tupui
Copy link
Contributor Author

tupui commented Jan 4, 2024

Seems to be working!!! Thanks @drammock for tracking this one down. I will also post on SciPy's PR.

@12rambau
Copy link
Collaborator

12rambau commented Jan 4, 2024

I'll release 0.15 then and close this issue, thanks for staying around !

@12rambau
Copy link
Collaborator

12rambau commented Jan 4, 2024

this patch is now available on pypi in v0.15.1

@12rambau 12rambau closed this as completed Jan 4, 2024
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 a pull request may close this issue.

10 participants