106

The slowest part is a dozen of diagrams in TikZ.

7
  • 27
    TikZ is dangerous. When you realise that it's far too slow, you have already invested a lot of time creating the illustrations, and it's too late to change the tools. Of course this doesn't help you now, but I'd suggest that it's best to avoid TikZ in future. (External compilation helps, but with it you also lose some of the best features of TikZ - tight integration with your Latex source code. When I got really desperate with a particular TikZ-heavy document, I did editing & compilation over an ssh connection on a very fast Unix server.) Commented Jul 26, 2010 at 20:15
  • 13
    @Jukka: but isn’t tight integration really rare? And for all other cases, externalized graphics work really well. All in all, I’d say that you’re overly pessimistic, except if your document uses very complex overlays that interact heavily with the rest of the document. Commented Jul 26, 2010 at 20:21
  • 3
    @Konrad: Of course you are right, people have different needs. But the tight integration (single source file, single-step compilation, simple way to re-use the same set of macros in pictures and text, possibility to use loops and macros to generate a bunch of related illustrations and captions easily, etc.) was one of the main reasons why I initially got excited about TikZ, together with its PDF support. However, I think that if you don't need the tight integration, then there are plenty of other options available as well (e.g., Xfig + a bunch of scripts; R). Commented Jul 26, 2010 at 20:43
  • 6
    Is this question a general question on performance, or is it a specific question about performance when using TiKZ? Commented Jul 26, 2010 at 22:20
  • The only feasible method is to selectively compile only the diagram you are working on (regional compilation) to get a fast iteration cycle. You don't have to externalize your diagrams, many of which better stay un-externalized.
    – YIchun
    Commented Apr 13, 2020 at 5:23

11 Answers 11

61

Read section 52, "Externalizing Graphics", of the PGF manual v3.1.9a.

8
  • 5
    If anyone is interested, I have a script that automates this process for a document with many tikzpicture enivronments. Ask a separate question and I'll share it! Commented Jul 26, 2010 at 22:10
  • 8
    tex.stackexchange.com/questions/1460/…
    – Neil G
    Commented Aug 10, 2010 at 6:23
  • Is it possible to answer Neil's question?
    – pmav99
    Commented May 12, 2011 at 16:19
  • 1
    This section is now 50.4 in the current pgfmanual
    – Joost
    Commented Apr 27, 2015 at 13:03
  • 1
    This section is now 53.4 in the manual.
    – Suthek
    Commented Jan 6, 2020 at 17:40
28

Make is Your Friend!

This problem was solved ages ago, so let's take advantage of all the nice tools Unix gave us!

The best solution I can think of for a large document is to simply not have any \begin{tikzpicture} or \tikz macros in it and do everything with \includepdf.

To this end, I made a makefile (for GNU Make) that looks (and I do mean looks – Makefiles are old technology – so old that tabs are actually significant syntax...) sort of like this for a project of mine:

TIME     = /usr/bin/time -p
LATEXMK  = latexmk -silent -f -g --pdf
PDFLATEX = pdflatex -interaction=batchmode
PDFCROP  = pdfcrop
RM       = /bin/rm

default : Project.pdf

StandAloneGraphicsTeXFiles = $(wildcard *_sag.tex)

PDFGraphics = $(patsubst %_sag.tex,%_sag.pdf,$(StandAloneGraphicsTeXFiles))

InputTeXFiles = $(wildcard *_input.tex)

%_sag.pdf : %_sag.tex
        $(PDFLATEX) $< 
        $(PDFCROP) $@ $@

Project.pdf : $(PDFGraphics) $(InputTeXFiles) Project.tex
        $(TIME) $(LATEXMK) Project.tex

clean : .PHONY
        $(RM) -f -- *.aux *.bak *.bbl *.blg *.log *.out *.toc *.tdo _region.*

depclean : clean
        $(RM) -f -- *_sag.pdf

distclean : depclean
        $(RM) -f -- Project.pdf

.PHONY :

How do I use that?!

Whenever you'd use a tikzpicture environment or a \tikz macro, give your picture a suggestive name, say riemann_sum, put the TikZ code in a single standalone document (with some boilerplate such that it matches the style of your main document. For example we don't want Computer Modern in our pictures while the main document is typeset with Times or a 10pt/12pt font size clash) called riemann_sum_sag.tex and use \includepdf{riemann_sum_sag} instead. The goal is to not have a single picture being compiled when you run make without having modified a *_sag.tex file. If this is not possible because you need to \ref something inside a picture, then so be it, but try to keep that to a minimum and instead choose good captions or something.

You'll also notice that there is a rule for files matching *_input.tex. This is for splitting the project into multiple files which is of course always a good idea when doing large projects. The rule detects whether such a file has been modified, and if it has triggers a recompilation of the document. LaTeX's \includeonly feature might be a good companion to this.

1
  • 5
    Might I suggest you add an explanation of the -j flag for make files? That would speed it up by a factor equal to the argument of -j. :)
    – nickpapior
    Commented Mar 12, 2013 at 18:47
22

You can try creating a Precompiled Preamble (Wayback machine snapshot) or "format" for your document. This technique basically caches all the computations that LaTeX does when processing the preamble which is the stuff before \begin{document}. If your packages, macro definitions, etc are not changing it can produce a noticeable savings in time.

Update

Just noticed the reference to TikZ- in this case Scott's suggestion is the most pertinent.

Update 2:

The mylatexformat package can aid in creating and using format files.


See also Speeding up compilation using precompiled preamble with LuaTeX

2
15

Another way to speed-up compilation is to figure out what it is that is making each picture slow and then do something about it. As a case study, it just took nearly 18s to compile the source for this seminar. That's a bit long for a compulsive recompiler like me! Watching the page numbers go by, I could see that the picture that takes the longest is on page 51. The source of this diagram is available and it's fairly clear that it's the torus that takes the time (there are two foreach loops, nested). If you look carefully at the start of the foreach loops, you'll see:

\foreach \t in {\start,\tsnd,...,\tend} {
\foreach \s in {0,\sstep,...,\send} {

Even without looking at how the various commands are defined, it's clear that by changing them, I can change how many times these loops loop. Thus when I'm working on the diagram itself then I can use values that I'll use in the final document, but when I'm working elsewhere in the document, I can set them to something a little more user-friendly. Indeed, near the top of the document, I have:

% Only do every \step th step in draft mode when drawing pictures
\ifdraft
\def\step{10}
\else
\def\step{1}
\fi

which sets a global option (of course, I can override it for a particular picture when I'm actually working on it). (Note: \ifdraft isn't a standard "if", hopefully it's obvious what it does.)

One more tip: when working on a document with lots of diagrams, I often have a "diagram-only" file for working on a specific diagram at a time. This has the same preamble as my main document but only one diagram in it (the one I'm currently working on). It's like a scrap piece of paper. To save my working, when starting to a new picture then I just put a \end{document} in above the previous picture.

1
  • @ebo \begin{todo} \item Sort out broken links \end{todo} Commented Jun 7, 2017 at 21:23
9

I use plain XeTeX, so the externalization described in the TikZ manual doesn't work for me. But I've found a neat way to speed up my compilations.

Like Andrew shows in his answer, I split the figures to their own .tex file, so that I have maindocument.tex and maindocument-figs.tex. Inside maindocument-figs.tex, I make sure the fonts, baselineskips, etc. are the same between the two TeX files. Then I use a simple macro inside the -figs.tex file:

\def\minpage#1{\setbox0\hbox{#1}\dimen0=\ht0\advance\dimen0 by\dp0%
  \special{papersize=\the\wd0,\the\dimen0}\box0\eject}

which will make a single page of the content I feed it with, having the contents dimensions (more or less). There would be some extra space though which needs to be removed by

\voffset=0pt\hoffset=0pt
\advance\voffset by-1in\advance\hoffset by-1in

Now after I do \minpage{\tikzpicture ... \endtikzpicture}, I'll get a PDF with each of those \minpages on their own page.

Then on the maindocument.tex side of things, I have another simple macro:

\newcount\figcount
\def\fig#1{%
  \global\advance\figcount by1
  \topinsert
    \centerline{\XeTeXpdffile "maindocument-figs.pdf" page\the\figcount}
    \smallskip
    \centerline{Figure \the\figcount:\enspace\it #1}
  \endinsert
}

Now every time I want a figure I can just write \fig{The caption of the figure.}.

Of course, if I make changes to the -figs.tex file, I need to recompile that, and the maindocument.tex file.


I realize the question title asks specifically about LaTeX, but in the question body the slowdown is attributed to using TikZ, so I hope I can share my experiences even though not with LaTeX.

8

If it's your TikZ graphics that are taking a long time, use the standalone package to have them in a separate file.

As for more general hints, if you are compiling a big document, but you only really need part of it to compile (e.g. if you're compiling a book, but only chapter 3 has changed) split the file into several files and use \include to put it all together. Then you can use \includeonly{chapter3} for example, and only chapter 3 will be compiled. This is useful for compulsive recompiliers like me...

2
  • 1
    Ah, I just found this question and naturally wanted to add standalone. Thanks for mentioning it. The upcoming version will include some feature which allows to compile included standalone pictures from the main file and include the resulting PDF in the next runs. This heavily decreases the compile to while only slightly increases the file size. There will also be the possibililty to automatically recompile the standalone pictures when the TeX file is newer than the PDF. Commented Apr 4, 2011 at 18:34
  • it's a pity this answer is so far down. I got to this question by googling, and using [[standalone]] is really easy to set up and doesn't require any outside-of-tex tinkering.
    – Joris
    Commented Mar 13, 2023 at 8:32
6

Different from all the higher ranked answers, this solution requires you use no new package, no change/rearrange/addition to your source files, no externalization of figures (some figures aren't supposed to).

Some LaTeX environments support a feature called regional compilation where you can compile only a part of the document and view it. For example, AUCTeX supports this. It's perfect for slides since most of the time you are working on only one specific slide. Of course, the following are in Emacs.

The process is really easy:

  1. (do this once) mark the region you need to compile. It can contain one or several frames (If it contains one frame, you can use C-c . to mark it.) Use your marking skills to get the right region selected.

  2. (do this once) C-c C-t C-r to pin the region for partial compilation.

Then follow you previous workflow: C-c C-r to compile, C-c C-r again to view or refresh the viewer.

For all things I learned during making slides, it is the regional compilation in AUCTeX that has helped the most. A full compilation only happens when I want to ship the whole document.

3

A more crude version of Andrew's suggestion would be:

\usepackage{verbatim}
\renewenvironment{tikzpicture}{%
  Picture%
  \begin{comment}%
}{%
  \end{comment}%
}

This inserts the text "Picture" instead of any tikzpicture environment. The advantage of this method is that this is all you need to change, whereas the "externalization" or "standalone" solutions require (minor) modifications in other places, be it the build procedures or the files that contain TikZ code.

1
  • This doesn't seem to work; it fails with "File ended while scanning use of \next". I think it's because inside the {comment} environment TeX is looking for \end{comment}, and is not expanding macros; it does not see any such thing, because the source file says \end{tikzpicture} instead. Commented Nov 26, 2021 at 10:04
2

I am unsure for TikZ, but for XY-pic the command \CompileMatrices doesn't recompile your arrays, greatly speeding up the compilation time.

2

I find it usefull to use a small work-around. I do this:

\newcommand{\ready}[1]{\fbox{Here will be a picture}}
\newcommand{\notready}[1]{\fbox{This picture isn't finalized, yet}}

Then when I want to draw a large picture I do something like this:

\begin{tikzpicture}
%\ready
{
\draw (0,0)--(1,1);
...
<and a whole lot more>
...
}
\end{tikzpicture}

When I am actually working on the picture I place the %-sign before \ready. When I'm not any more, I remove the %-sign before \ready (or \notready depending on which one applies). The ready commands now make sure that someting is actually printed (can be handy when in a figure float, for example). The very long tikz-picture is not compiled however, reducing your compiling time to normal.

When I want to compile my final document, I simply change to

\newcommand{\ready}[1]{#1}
\newcommand{\notready}[1]{\ThisPictureStillNeedsWork}

This way, all the tikzpictures that were ready will be compiled. If you have overlooked some pictures that were not ready, then you'll be warned by an error-message, bacause \ThisPictureStillNeedsWork was never defined.

I know it's not really a clean solution. But it's hardly any extra effort and I don't accidentally end up with pictures in my final document that are acctually still under construction. But most importantly, I only compile (large) tikz-pictures when there is actually a change to be seen.

1

I don't use TikZ, so I've no idea if this will help with TikZ-related slowness. But, the question asks how to speed up compilation (in general).

Using the draft option in your \documentclass declaration will cause many different packages to skip some steps or niceties and will thus give a speed boost. When compiling the final document, either remove the draft or replace it with final.

1
  • 2
    This, however, doesn't seem to be working for TikZ :/
    – Jóhann
    Commented Mar 30, 2011 at 12:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .