I recently went through the process of optimizing the build time on one of my projects. I started at ~3.08s, and got it down to ~1.6s. The project is around 7000 non-comment-non-whitespace LOC. I timed the build in a pretty non-rigourous fashion (I just timed the python script that kicks off a command-line call to dmd and waits for it to finish), however I only cared about making changes that resulted in large improvements to the build time, so this was good enough for my purposes.

I too found that template instantiation was responsible for a lot of the extra build time. I found running dmd -v very helpful in tracking down excessive template instantiations or other places where the compiler was doing a lot of work that could be avoided.

The steps I took were as follows:

- Start (3.08s)
- I was using custom assert function that grabbed __LINE__ and __FILE__ as template arguments, meaning each of the ~130 assert calls required a separate instantiation. I switched to passing those in as run-time arguments (2.85s) - I had a similar wrapper around some logging functions in std.experimental.logger. I made a small change to std.experimental.logger to allow a call path with no template instantiations, and similarly fixed my own wrapper. I had ~70 logging calls (2.7s)
- Recompiled DMD with VS2015 (2.5s)
- Overclocked my CPU :D (2.3s)
- Created a file called heavytemplates.d that built to a .lib in a separate build step. The first templates I pulled out were a couple std.regex calls and instantiations (1.9s)
- Changed some tuples into structs (negligible improvement)
- Pulled several templates into heavytemplates.d that instantiate recursively over the Gamestate (a very large struct) (1.75s) - Pulled out template instantiations used by msgpack-d, which also instantiate recursively over the Gamestate for save/load of the game (1.6s)

Of all of these, I was most surprised by the gain I got from pulling out std.regex calls into a separate build (0.4ms). Whether or not I used compile-time regexes didn't seem to affect build time substantially, just that I used anything at all. Also, whether I had one regex call or five didn't seem to matter, likely because std.regex instantiates using the string type as a parameter, and I just used plain old 'string' for all regex uses.

There's still work I could do, but at some point I start to get diminishing returns, and have to actually work on features instead of just optimizing my build :D

Reply via email to