Full build with PDF is taking more than 24h #169
Copy link
Copy link
Closed
Description
Today we're building 6 versions for 13 languages (that's 78 builds).
I'm doing some tests on my machine to get an idea:
- An HTML build takes 55 s.
- A full build (html + text + PDF A4 + PDF letter + epub + texinfo) takes around 21 min, composed of:
- 1 min for
make htmlcomposed of:- 50 s for sphinx-build
- 10 s of html archiving
- 40 s for
make text - 9 min for the A4 PDF build composed of:
- 1 min for
make latex PAPER=a4 - 8 min for
make all-pdf(inbuild/latex/) (less if run again, like 1 s if not removing PDFs, or 1 min after removing PDFs). Can be cut down to 6 min with-j 4.
- 1 min for
- 8 min 30 for the letter PDF build, roughly similar to A4 unsurprisingly
- 1 min for the epub build
- 1 min 30 s for the texinfo build
- 1 min for
So a complete rebuild should take ~27h (on my machine, the server may have a different CPU).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
egeakman commentedon Oct 5, 2023
Building only the changed branches and languages, how does it sound?
I don't have much information about the server but here are some ideas:
git pulleverytime we build; we can insteadgit fetchin each repo and see if there are any changes, and if that's the case we can pull and build.egeakman commentedon Oct 5, 2023
Additional question for @JulienPalard: Are non-bugfix and non-stable releases only rebuilt manually or is there a cron?
JulienPalard commentedon Oct 5, 2023
EOLandsecurity-fixesbranches are only built manually, yes.egeakman commentedon Oct 5, 2023
What do you think about the idea in general @JulienPalard?
JulienPalard commentedon Oct 5, 2023
(see the git_clone function in the script).
Maybe, yes. But to do it cleanly we should only rebuild if the
Doc/directory changed, but doable and cheap as we keep the cpython clone.Currently a git log shows that (for the Doc/ directory) changes are:
A change cpython side should trigger a rebuild of all languages for the given branch (while a change for a language should not trigger a rebuild for all branches: translation repo has a translation branch per cpython branch).
Translation side I expect less changes, except for a few crons like for python-docs-ja which synchronizes daily. Also changes are for a single branch so they invalidate a single cpython branch.
So instead of rebuilding 78 docs per day, just looking at the cpython side, we'd rebuild like 26 docs daily (main and 3.11) which should take like 9h.
About how to do this, we could store at build time the cpython commit sha and the translation commit sha in a file, and at build time call a dedicated function to check the shas against the repositories to see if a build is needed or not.
Seems doable.
picnixz commentedon Oct 8, 2023
@JulienPalard Someone opened an issue on Sphinx in order to know whether we could speed-up things on our side. I am not quite confident in that since most of the build time is actually the PDF build. It is possible to know why
make all-pdfis so slow? is it only because there are a lot of pages to write? or is it because of the underlying language? (iirc, jp builds don't build with plain pdflatex).Another possibility is to change the way the PDF are created. We (Sphinx) could technically add a builder which, instead of outputting LaTeX code, outputs some other kind of typesetting language that can still be converted to PDF faster than LaTeX.
JulienPalard commentedon Oct 11, 2023
Hi @picnixz, thanks for jumping in!
I'm just a user of LaTeX, I don't know much. I know our biggest file is
library.texwith 288k lines of LaTeX, generating a 11MB PDF file.make all-pdfrunslatexmkfor each.texfiles, which in turn runsxelatex. So I tried just runningtime latexmk -pdf -dvi- -ps- library.tex, it takes 1 min 16s (on the same laptop used for the timings in the first post). same timing for the underlying command:xelatex -recorder library.tex.Those timings can be reproduced on a cpython clone after building latex file:
It reminds me of something about running it in a loop until the output does not changes..., which strace confirms:
Which also can be confirmed by reading the console log (I choose a smaller file to get readable output):
Also noticed, from
xelatexoutput:this is probably less than ideal.
I tried to use
perfto get some insights about what's slow inside xetex, if I read this correctly that's the parsing of the input file that's slow, can be reproduced using:it looks like this:
Probably yes,
library.pdfis 2318 pages, or lots of latex to parse if my perf reading is good.Looking at the server logs, yes
jpis slower than all the others. It takes like 1h30 while the other take like 30mn (for a full build of text, html, pdfs, ...). All builds are using xelatex while jp builds are usinglualatex. As it's the only one I won't focus on this one.It would be possible to build PDF using weasyprint.
m-aciek commentedon Oct 11, 2023
It looks like a potential alternative for PDFs building is using Rinohtype. It provides a drop-in replacement for Sphinx PDF builder and is a direct PDF builder. Still in beta though.
picnixz commentedon Oct 12, 2023
Thank you very much for your report !
Now I'm a bit confused about these timings:
Maybe I misunderstood, but why does the second command takes 4 min 13s but you told me it took 1min 16s? I also think the last command should be
cd Doc/build/latexinstead ofcd Doc/build/html.Yes, it's because of how LaTeX is structured with this token based approach + expansions. Depending on how expansions are done, it may enormously slow down the build. I am wondering whether breaking down
library.texinto smaller pieces that are put together at the end would improve or not the timings.In conclusion, I don't think we could do much except:
By the way, how much is allocated to build the documentation on Python servers? because a straightforward solution is simply to allocate more resources and run everything in parallel (but again, funds are required and I don't know if the server is like a super-mega-huge-powerful server). In the end, if you need to rebuild 26 docs per day (assuming you can reduce from 70+), the you "simply" need a more powerful unit.
JulienPalard commentedon Oct 12, 2023
That's because
latexmkrunsxelatexin awhile True:loop until the output stabilizes. Looks like it had to run it 4 times to reach stabilization (I have a few paragraph in my last message about it, search for 'strace' and 'rerun').I really don't know if there's a way to forge a latex file that necessitates less re-runs.
Probably just me manually fixing the commands for readability (and breaking them while doing so, haha).
picnixz commentedon Oct 12, 2023
Ah sorry! yes I overlooked that (I was a bit confused actually because I assumed that the ~1min was the output of
time). Now, the question is: is it possible to avoid usingxelatexactually and onlypdflatex?Also, since it tells us "or use package
bookmark", maybe this could solve the issue (though I don't know how). Nevertheless, yet another alternative is to run the latex command only once and check whether more compilation is needed (and not let latexmk decides by itself). I'm not sure whether the 4 runs are actually needed to solve all the references (in general, we need 2 reruns but here I'm wondering why we actually need 4).Btw, I'm sorry but I cannot really reproduce it myself because I need to install fonts that I don't have (and move them around files + adding paths or so) (but since you've got everything running on your side + timings are for your machine, the comparison is more fair).
JulienPalard commentedon Oct 12, 2023
IIRC we use xetex instead of pdflatex for its unicode awareness.
Tried:
JulienPalard commentedon Oct 22, 2023
Since #171 has been merged, there has been a build taking 13.6 hours. That's better, probably still room for enhancements.
JulienPalard commentedon Oct 27, 2023
I changed the build cron so it starts hourly, so instead of doing nothing for 24h-13.6h the script checks if there's something to build.
In the logs here's what I see:
hugovk commentedon Dec 8, 2023
The last https://docs.python.org/3/ build was at Dec 07, 2023 (12:24 UTC).
The 3.12.1 release was at something like Dec 08, 2023 (00:45 UTC).
As there's no public logs yet (#174), I'm curious why there's been no build yet from the hourly cron. Is the queue full, or maybe something else up?
This relates to https://discuss.python.org/t/python-3-12-1-now-available/40603/2?u=hugovk: a request for release announcements to include the changelog, but the changelog at https://docs.python.org/3/whatsnew/changelog.html still shows "Next" and not "3.12.1".
25 remaining items
AA-Turner commentedon Aug 17, 2024
It turns out we have inadvertently been running the full
latexmkprocess twice for every build, since around 2010. Luckily, this is fixable.The LaTex build in Sphinx generates a makefile which we use to run latexmk and generate the actual PDFs from the
.texsources that Sphinx creates. In CPython'sDoc/Makefile, we call that makefile in a submake:(cd build/latex; make clean && make all-pdf && make FMT=pdf zip bz2).Considering the generated Makefile at
Doc/build/latex/Makefile, theall-pdftarget depends on$(ALLPDF), a list of every desired PDF file. Thezipandbz2targets also depend on$(ALLPDF). All three ofall-pdf,zip, andbz2are.PHONYtargets, which are evaluated every timemakeruns. Normally, this wouldn't present an issue, as thezipandbz2targets depend on$(ALLPDF)rather thanall-pdf, so make would know not to rebuild the PDF files. The issue becomes clear with the%.pdftarget. By depending on the.PHONYtargetFORCE_MAKE, PDF files are forcibly regenerated on both invocations ofmake, bypassing the inbuilt artefact caching.Resolving this is straightforwards, and I have a branch prepared to open a PR to CPython. EDIT: I have opened the PR at python/cpython#123113.
Sample timings (8 core CPU, via WSL):
-xelatexmake -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2make -j LATEXMKOPTS="-xelatex" all-pdf && make FMT=pdf zip bz2-xelatexmake -j all-pdf && make FMT=pdf zip bz2make -j12 all-pdf && make FMT=pdf zip bz2I am proposing to use the final option, as whilst not the absolute fastest, it helps to mitigate scheduling problems, and the docs server only has 4 CPU cores, per Hugo's comment. It seems that
-xelatexdoesn't make a massive difference here.A
jfbu commentedon Aug 17, 2024
Good catch! The blame is on me at sphinx-doc/sphinx@409605d, but to my defence former Makefile did 5 (pdf)latex builds each time. Actually re-reading your post I am wondering if
latexmkreally triggers againxelatex. It should say something like this (this is an example on a dummy project)jfbu commentedon Aug 17, 2024
I think one has to make sure none of the 4 or 5 biggest files end up being handled by same core which may require a more complex layer to first list files as per decreasing filesizes of the
.texand feed them in that order tomakeas pdf targets.Yes Sphinx docs is too optimistic about this. It makes a difference when build documents does a ton of graphics inclusions.Sphinx docs does say it makes a difference in case of tons of graphics inclusions.hugovk commentedon Aug 25, 2024
With @AA-Turner's latexmk improvements (#169 (comment)) we're saving about a third of the time!
Here's a difference in the build times (not publish and so on) for a full set of 3.14 builds:
PS Here's the separate before and after times, and the script I used to get the times from the server build times.
before
after
calc-times.py
jfbu commentedon Aug 25, 2024
If you can build in an environment with a LaTeX distribution based upon TeXLive 2019 you will probably observe 30% or more additional gain. See this comment. I can not guarantee it completely because the comment compared builds on TL2019 and TL2024 and you use a Debian TL2023, so the gain might not be as much (I currently can not test on a TL2023). The PDFs will be exactly identical.
edit: I mean will look and print identical. Perhaps things are different regarding copy-paste from PDF and some other matters.
(I can not quantify at this time if the change from TL2023 to TL2024 induced the major part in slow-down of LaTeX kernel, or if it occurred earlier).
hugovk commentedon Aug 25, 2024
Another 30% or more would be very welcome! But I'm not too sure if we should downgrade to an unsupported version? (Or how to do it.)
jfbu commentedon Aug 25, 2024
A docker image is available for all TeXLive versions since 2014. The problem is that it contains the full thing which is much much more than what is strictly needed for Sphinx
make latexpdfeven leaving aside all sources and all documentation. Unfortunately I have personally no experience with this (having multiple TeXLive's on my computer already there), and to start with I have no idea if you can use such a Docker image and if its large size is an impediment (and I have other tasks now).There is a sphinx-latexpdf Docker image used for our CI, if I knew the recipe I could modify it to use TeXLive2019. And in the process try to use a much smaller part of full TeXLive hence construct a much smaller Docker image. But this is time-consuming task for which I don't have the immediate qualifications.
hugovk commentedon Sep 18, 2024
Update, we've cut the build times by around another third, by cutting about 15h per full build loop through dropping the letter PDF build (and keeping A4 PDF):
And by about an extra half an hour by re-using an HTTPS connection for purging CDN URLs:
AA-Turner commentedon Sep 23, 2024
It seems we're currently running around 10h 40m for each version -- Python 3.13 hasn't done a full rebuild in a while as the last commit was a fortnight ago (save around a dozen in the last half-hour!). This would be roughly 32 hours for a full rebuild of 3.12--3.14.
Timings:
(reason is 'translation' if an updated translation caused the rebuild rather than updated docs, and 'FULL BUILD' captures the end of a full rebuild loop. The loops that are 'empty' but around 30m long attempt a build of
fr/3.13and fail, see #187)A
hugovk commentedon Sep 23, 2024
This initially caught me by surprise but is expected; the 3.13 branch is locked for RC2, so there's not been much merged on the branch recently:
merwok commentedon Oct 1, 2024
This is the recipe: https://github.com/csotomon/sphinx-docker/blob/master/latexpdf/Dockerfile
AA-Turner commentedon Oct 1, 2024
That link is to a fork, though it's unclear -- the up-to-date dockerfile is at https://github.com/sphinx-doc/sphinx-docker-images/blob/master/latexpdf/Dockerfile
AA-Turner commentedon Oct 2, 2024
I suggest that we close this issue in favour of #209, now that python/docs-community#131 has been implemented. The non-HTML archive builds still take a while, but it's a manageable duration and we now have the luxury of adjusting the frequency of those builds to e.g. once every two days rather than daily.
Thank you to everyone involved for the help in reducing build times, we have made significant strides here in a challenging problem straddling multiple teams, projects, and repos.
A
hugovk commentedon Oct 2, 2024
Here's a summary of the current times, much improved:
python/docs-community#131 (comment)
Yes, let's close and continue in other issues as needed.
Thanks all!