Categories
Bloggers
Blogs RSS feed

How to speed up the build of your solution in Visual Studio

by Momchil Mitev

The time it takes to build your solution in Visual Studio could greatly hinder your performance. Especially if you got to some trial and error desperate measures which let's face it - everyone has to do from time to time.

Let's start with our experience. Few years back in SItefinity we managed to reduce the build times of the Telerik.Sitefinity.sln several times with some simple changes. When the solution started to rapidly grow on project numbers we noticed that the build times increase exponentially. Digging a bit got us to a bottleneck that once sorted out gave us improved build times by 5 minutes. Of course those times could be very different on your solution depending on its size the hardware you are using etc.

Optimization Build time Rebuild time
No ~3 min 30 sec ~6 min 50 sec
Yes ~1 min 30 sec ~1 min 50 sec

 

We achieved this by avoiding a lot of unnecessary .dll copy operations during the build. Those copy operations occur due to a setting on a project reference or assembly reference called CopyLocal.
By default all project references have their CopyLocal property set to true. If “Project A” references “Project B” and the reference is set to CopyLocal=true all output from “Project B” (dlls, pdbs, XML) will be copied to the output directory of “Project A”.
Here is a visual representation:

 Diagram of the dlls copy operations done during the build if the CopyLocal is set to true

 We had to change 2 things to avoid this:

  1. We changed all projects inside Telerik.Sitefinity.sln so that all their project references’ copy local setting is defaulted to false. This is done only if the build is inside Visual Studio as it causes missing dlls in the _PublishedWebSites folder when the build is invoked with msbuild and specific OutDir (publishing). The MSBuild targets file that we added to all .csproj files can be found on the bottom of the post.
  2. We changed the output of all projects that SitefinityWebApp depends on to be the SitefinityWebApp/bin folder and not their own bin/ folders.
  3. We changed all dll references CopyLocal values to false.

Here a visual representation of the process after the change:

Build process in Visual Studio with copylocal set to false

 

As you can see this is a much more fragile setup as it requires a manual settings for each new added project but I am sure you will agree this is an acceptable trade-off.

Another conclusion that can be made is that this setup will not work for solutions that have multiple starting projects like multiple websites, console applications, desktop apps etc. In this case another step will be required for example on after build that will take the resulting dlls from a specified folder and copy them to the startup projects.

Here is the ProjectReferenceModifier.targets that we wrote and included in every .csproj file of the solution:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--Set the copy local for project references to False only if the build is Inside Visual Studio or no OutDir was specified.-->
  <ItemDefinitionGroup Condition="$(BuildingInsideVisualStudio)=='True' OR ($(OutDirWasSpecified)!='True' AND $(WebProjectOutputDirInsideProject)!='True')">
    <ProjectReference>
      <Private>False</Private>
    </ProjectReference>
  </ItemDefinitionGroup>
</Project>

2 comments

Leave a comment
  1. Derek May 17, 2014
    This will work well for big solutions with deep project reference trees.
  2. Krutarth Soni May 23, 2014
    Thank you for this this is more helpfull for me.

    Leave a comment