2

My Buildprocess works fine but it takes nearly 3 seconds for a really small project.

How could i speed up the build process?

The logfile is to big for posting it. Feel free to ask questions about the logger output, i will then post the requested part.

C# Methods to build the project

private void CompileCode() { using (var buildManager = new BuildManager()) { var result = buildManager.Build(this.CreateBuildParameters(), this.CreateBuildRequest()); if (result.OverallResult == BuildResultCode.Failure) { // Error handling var stringbuilder = new StringBuilder(); using (var reader = new StreamReader(NameDebuggerLogFile)) { stringbuilder.Append(reader.ReadToEnd()); } throw new CompilerException(stringbuilder.ToString()); } } } private BuildParameters CreateBuildParameters() { var projectCollection = new ProjectCollection(); var buildLogger = new FileLogger { Verbosity = LoggerVerbosity.Detailed, Parameters = "logfile=" + NameDebuggerLogFile }; var buildParameters = new BuildParameters(projectCollection) { Loggers = new List<ILogger>() { buildLogger } }; return buildParameters; } private BuildRequestData CreateBuildRequest() { var globalProperties = new Dictionary<string, string>(); var buildRequest = new BuildRequestData(FolderPath + NameProjectFile, globalProperties, null, new[] { "Build" }, null, BuildRequestDataFlags.ReplaceExistingProjectInstance); return buildRequest; } 

Project file used for the build process

<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <PropertyGroup> <AssemblyName>GeneratedFlexForm</AssemblyName> <OutputPath>DLL</OutputPath> <OutputType>Library</OutputType> <DebugType>none</DebugType> <DebugSymbols>false</DebugSymbols> <Optimize>false</Optimize> </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Xml" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.ServiceModel" /> <Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Web" /> <Reference Include="System.Web.Services" /> <Reference Include="System.Drawing" /> <Reference Include="System.Design" /> <Reference Include="System.Data" /> <Reference Include="System.Core" /> <Reference Include="System.Management" /> <Reference Include="System.Configuration" /> <Reference Include="System.Xaml"> <RequiredTargetFramework>4.0</RequiredTargetFramework> </Reference> <Reference Include="WindowsBase" /> <Reference Include="PresentationCore" /> <Reference Include="PresentationFramework" /> <!--<Reference Include="FlexForms.Core" />--> <Reference Include="FlexForms.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>Library\FlexForms.Core.dll</HintPath> </Reference> <Reference Include="Gizmox.WebGUI.Forms"> <SpecificVersion>False</SpecificVersion> <HintPath>Library\Gizmox.WebGUI.Forms.dll</HintPath> </Reference> <Reference Include="Gizmox.WebGUI.Common"> <SpecificVersion>False</SpecificVersion> <HintPath>Library\Gizmox.WebGUI.Common.dll</HintPath> </Reference> <Reference Include="FlexForms.ServiceProviders"> <SpecificVersion>False</SpecificVersion> <HintPath>Library\FlexForms.ServiceProviders.dll</HintPath> </Reference> </ItemGroup> <ItemGroup> <Page Include="FlexForm.xaml"> <Generator>MSBuild:Compile</Generator> <DependentUpon>RadioButtonValueConverter.cs</DependentUpon> <SubType>Designer</SubType> </Page> <Compile Include="FlexForm.xaml.cs"> <DependentUpon>FlexForm.xaml</DependentUpon> <SubType>Code</SubType> </Compile> <Compile Include="UserCode.cs"> <SubType>Code</SubType> </Compile> <Compile Include="RadioButtonValueConverter.cs"> <SubType>Code</SubType> </Compile> <Resource Include="datacontext.xml"/> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> </Project> 

Logger output collected during the build (just the last lines due to file size)

Done building project "projectfile.csproj".

Build succeeded. 0 Warning(s) 0 Error(s)

Time Elapsed 00:00:02.68

EDIT:

I hope i'm allowed to quote Seva Titov here:

Building WPF is really tricky, for example XAML files get re-compiled twice (see MSDN). You cannot easily replicate it with just csc.exe. If you have XAML in your project, you have to use MSBuild. – Seva Titov

Thats why i have to stick to MSBuild.

Anyway, i had a few ideas to improve the performance:

Problem 1: This is a snippet from my logfile, which says that MSBuild will look after .winmd, .dll and .exe files whiles resolving the dependencies.

AllowedAssemblyExtensions: .winmd .dll .exe 

Since i have only .dll files i would like to disable that MSBuild considers .winmd files which is the case for nearly all of my dependencies. (example below)

Primary reference "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35". Resolved file path is "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\PresentationCore.dll". Reference found at search path location "{TargetFrameworkDirectory}". For SearchPath "{TargetFrameworkDirectory}". Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\PresentationCore.winmd", but it didn't exist.

Solution: 1 I had to modify my CreateBuildRequest() method:

private BuildRequestData CreateBuildRequest() { var globalProperties = new Dictionary<string, string>(); // Related to idea 1 globalProperties.Add("ExpandSDKAllowedReferenceExtensions", ".dll"); globalProperties.Add("AllowedReferenceAssemblyFileExtensions", ".dll"); globalProperties.Add("AllowedReferenceRelatedFileExtensions", string.Empty); // Related to idea 2 globalProperties.Add("BuildProjectReferences", "false"); globalProperties.Add("BuildInParallel", "true"); var buildRequest = new BuildRequestData(FolderPath + NameProjectFile, globalProperties, "4.0", new[] { "Build" }, null, BuildRequestDataFlags.IgnoreExistingProjectState); return buildRequest; } 

EDIT2: Idea 2: does anyone know how to include the /maxcpucount or /m switch to build my project in parallel? its explained on this MSDN page but i can't figure out how to apply it to the project file listed above

Solution 2: See Solution 1, but it didn't change much.

EDIT3: After hours of playing around, i guess i will have to give up. The only option i see is to reduce the dependencies in general. But i will come back on this later.

A bit unrelated:

> Task Performance Summary: > 0 ms CreateItem 1 calls > 0 ms AssignCulture 1 calls > 0 ms CallTarget 2 calls > 0 ms FindAppConfigFile 1 calls > 0 ms Delete 4 calls > 0 ms GetFrameworkPath 1 calls > 0 ms ConvertToAbsolutePath 1 calls > 0 ms MakeDir 1 calls > 0 ms Message 5 calls > 0 ms AssignTargetPath 6 calls > 1 ms FindUnderPath 5 calls > 1 ms FileClassifier 1 calls > 1 ms RemoveDuplicates 2 calls > 1 ms CreateCSharpManifestResourceName 1 calls > 1 ms ReadLinesFromFile 1 calls > 15 ms ResolveAssemblyReference 1 calls > 21 ms ResourcesGenerator 1 calls > 56 ms Copy 2 calls > 299 ms GenerateTemporaryTargetAssembly 1 calls > 502 ms Csc 2 calls > 725 ms MarkupCompilePass1 1 calls > 814 ms MarkupCompilePass2 1 calls > > Build succeeded. > 0 Warning(s) > 0 Error(s) > > Time Elapsed 00:00:02.27 
13
  • How fast do you need it to be? Commented Mar 27, 2013 at 12:05
  • as fast as possible. The code above is used to generate a XAML Window during application runtime. The Buildprocess is executed when a user clicks the "request form" button. I don't want them to wait ;) Commented Mar 27, 2013 at 12:11
  • 4
    Why are you compiling code at all? Why have you made that design choice? Build the form dynamically and you'll have your instant response time. And your code will not require a development environment to be available. Commented Mar 27, 2013 at 12:12
  • 2
    Anyway, if you want to compile faster, cut msbuild out of the loop. Call the compiler directly. Commented Mar 27, 2013 at 12:14
  • 1
    sorry for my imprecise answer, everything under 1,5 seconds would be fine for me (and my boss) Commented Mar 27, 2013 at 12:42

2 Answers 2

6

To answer your direct question, there's nothing much you can do to speed up msbuild. I'd expect it to run faster if your machine used an SSD, but that's probably not the sort of solution you are looking for.

The only other thing I can think of is to stop using msbuild altogether. All it does is drive the C# compiler. So why bother with msbuild at all? Just use the C# compiler directly. For example via CSharpCodeProvider.

Sign up to request clarification or add additional context in comments.

2 Comments

Building WPF is really tricky, for example XAML files get re-compiled twice (see MSDN). You cannot easily replicate it with just csc.exe. If you have XAML in your project, you have to use MSBuild.
You don't have to use MSBuild, it's just easier to do so.
-1

One easy way I can suggest is to utilize your multiple cores of the processor by giving an MSBuild property like in the command below:

msbuild default.msbuild /m:1 

I am not sure how the /m attributes takes effect internally.

EDIT:

As far as I had seen, the threading happens external to project. Multiple projects in a solution will run with one thread for each project in parallel. So you may not be able to add this as a project option.

But, in another Hanselman link I found a hack to get this incorporated in Visual Studio to run it along with Solution compilation. Please check this out.

Here it adds MSBuild as an external tool to run solution with this attributes.

4 Comments

where do i have to add the /m:1 option in my project file? this pages hanselman.com/blog/… is also about this command line switch, but i don't use MSBuild from the command line
I'm not sure about how to add this to the project file. I had used this only in command line.
/m to tell MsBuild use as many CPU cores as you have on your PC, /m:1 means let it only use one core which might be not that useful
@RinoTom - Your answer is misleading. /m:1 forces it to build with a single core and will disable parallelism. You should instead use /m to allow MSBuild to maximize cores or specify a number greater than 1.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.