As a developer I hate having to wait around for my pc to finish doing something. Whether it be something opening (Visual Studio), getting the latest svn updates (and it locking up my browser!?), and especially waiting for my code to build (locally, or via CruiseControl).

Obviously, the simplest solution is to throw more money at the problem and get a faster pc. But unfortunately not all of us have that luxury. 

There are quite a few tips/steps for speeding up the build though (if you are using NAnt), here are some of them.

Asynchronous Tasks (asyncexec)

Change To Our Build Time: reduced by 30-45 seconds

Not all tasks have to be run sequentially when running the build. A good example is running aspnet_compiler and unit tests, which can be run after the code has been compiled.

Jay Flowers has written a rather handy NAnt “asyncexec” task that allows more than one task to execute at a time.

I had problems using this task with NAnt 0.86b though, and couldn’t get the task to load. I can’t remember the exact reason, but it was due to a different assembly versions (NAnt 0.86 being newer has newer libraries). So, I set about recompiling Jay’s task, but again ran into another problem. VB! Anyway to cut a long story short, I used Reflector to pull out the C# code from a compiled version of the asynexec dll, and created a C# version of Jay’s task.

You can download the Huddle.NAnt.Utils.dll, or get the source (I’d recommend taking a copy of the source).

Using the task is fairly simple. Firstly make sure you have loaded it:

[code language=”xml”][/code]

I won’t go on about further usage too much, it’s best to refer to Jay’s blog to see a good example, and an update on the task.

Reduced Logging

Change To Our Build Time: reduced by a second or two

This change doesn’t represent a huge change in build time, but does make development time much easier.

By letting NAnt log just about anything, it firstly takes fractionally longer, and secondly makes it harder to see what has failed amongst all the logging.

There is a problem though. NAnt has a bug, where if you change the verbosity of a task, it still spits out the logging. Rory Primrose has explained the issue in detail, and also come up with a solution.

I’ve taken his LogLevel NAnt task and added it to our Huddle.NAnt.Utils (source, dll). The usage is very simple, you just wrap an existing task with the LogLevel task. For example:

[code language=”xml”] [/code]

MSBuild Multicore

Change To Our Build Time: reduced by 15 seconds

The amount of difference this will make depends upon how many projects you have in your solution. We currently have around 40, but I’m slowly trying to get that closer to 20-25. But it currently makes a difference of around 15 seconds if I build with multi-core on or off.

It’s a simple change to make. MSBuild has a /m commandline parameter which if added tells MSBuild to use all available processor core’s when building. We use Core2Duo’s here, (duals, not quads) so it offers some benefit. The same applies to our build server. For more information Scott Hanselman details using multi-core with MSBuild further.

As far as the build is concerned, your NAnt MSBuild task should look something like:

[code language=”xml”] [/code]

Project Count

Change To Our Build Time: reduced by 12 seconds

Another difficult one to measure. We did previously have around 60 projects in our solution at one time. The difference in MSBuild time from then, to now (with around 44 32 projects) was about 12 seconds on average. I would predict that if we got down to my desired project count of around 20-25 projects, build time would reduce by another 15-20 seconds.

The reasons are simple, physical is slower than logic. Building one project is fast, the more projects you add, the more files that have to be output, copied etc… Also adding more projects, from my experience, complicates your design and causes problems. Circular dependencies are probably the most common. You shouldn’t be using projects to separate your code.

Centralising Compilation Output

Change To Our Build Time: reduced by 5 seconds reduced by 10-15 seconds

I haven’t actually commited or tested this change hugely (see end of the point for an update), but so far it does look slightly faster. The idea is simple, rather than each project compiling to /bin/Debug, or /bin/Release, you make all of your libraries compile to a central bin directory. By doing so for each reference within a project you can set CopyLocal to false (it’s under the Properties for a reference). This stops dll’s being copied around as much to individual /bin/Debug directories, and hence speeds up compilation.

You can also do the same for 3rd party dll’s. We keep all of ours in a “lib” folder (as per Tree Surgeon). Upon compilation, these can be copied (using NAnt) to the central bin directory. For each project that references them, you can just set CopyLocal to false.

The only projects you won’t be able to do this for are the ones you will be deploying, namely Web Applications, Windows Applications etc… You’ll still want them to copy the files locally to their directory (for both internal libraries and 3rd party libraries). This isn’t too bad though, as you have still reduced the amount of files that are copied around.

I’m sure there is more than the 5 seconds I have found so far. I’m hoping for closer to 10-15 seconds for this change.

UPDATE – I’ve now got this in full flow. Well… nearly. I want to apply it to our unit test and integration test projects. Anyway it has made quite an improvement. The “CopyLocal” is where the big win is at (especially if you have a large number of projects and references). Looking over 12 projects, we were referening a number of large dll’s (NHibernate for example) that were being thrown around to numerous directories. This step stopped that happening, and in turn has got our build time down another 10 seconds or so. It now stands at about 80-90 seconds in total.


That’s it for now. A few steps for speeding up your build that are reasonably easy to implement. If you are stuck for time, I’d focus on the number of projects, and asynchronous tasks as they offer the biggest wins.

Request a Demo

© 2006 - 2021. All Rights Reserved.