On Mon, Feb 05, 2018 at 01:27:57PM -0800, H. S. Teoh via Digitalmars-d wrote: > One of my D projects for the past while has been taking unusually long > times to compile. This morning, I finally decided to sit down and > figure out exactly why. [...]
I don't want this thread to turn into ragging on std.regex, so here's the next instalment of this saga. After taking std.regex out of the equation, I found that there was still something else that was bottlenecking my builds. So I went for another hunt, and discovered another guilty party: std.format. ---- import std.format; void main() { format("a"); } ---- Here I found something interesting: compiling with -unittest takes over 0.8s. But compiling *without* -unittest takes only 0.4s. The compilation times of std.format itself aside (it's pretty heavyweight because of heavy template usage, and the recent compile-time format string checking, while pretty cool functionally, also comes at the price of heavier CTFE, i.e., slower compilation -- I'd like to leave digging into std.format for later), it's a little disturbing that compiling with -unittest *doubled* the compilation time. This reinforces a concern I've been having recently, that is, library unittests that get instantiated when user code is compiled with -unittest. I'll be the first to say that having built-in unittests in D has revolutionized the way I write code -- it has dramatically increased the average quality of my code. But its current simplicity comes at a cost: if you're using external libraries (i.e., outside the immediate codebase you're working with, so that includes Phobos), compiling with -unittest automatically inherits all unittests from all libraries that you import, even if said unittests have nothing to do with your own code. Put another way: why should you be concerned with Phobos unittests when you're building your own code? Phobos unittesting should have been (and is) already done by the autotester and CIs on github; there's no reason these tests have to be run over and over again in user code. So I'd like to propose that we do something similar to what we did with template instantiations a couple of years ago: make it so that unittests are only instantiated if the module they occur in is being compiled, otherwise ignore them (even in the face of -unittest). This way, adding unittests to Phobos won't cause unintentional slowdowns / unittest bloat across *all* D projects that import the affected Phobos modules. (Seen from this angle, it's a pretty hefty cost.) Of course, this statement has to be qualified a bit: it's probably still a good idea to instantiate unittests inside templates -- since ostensibly they could be sanity-checking specific instantiations of templates. Though I'd argue that 90% of the time, their location inside a template is a mistake; they really should be outside templates and only instantiated once, because generally they test specific instantiations of the template rather than implement generic tests that apply across all template instantiations. T -- Never step over a puddle, always step around it. Chances are that whatever made it is still dripping.