Microsoft.Net.Compilers 1.3.0-1.3.2
For unmentionable reason we are currently working on 160+ projects solution: .net mvc, .net 4.6.1, VS2015 update 3. The build takes ~3 minutes. After installing via nuget Microsoft.Net.Compilers in version 1.3.0 or 1.3.2 the build goes from ~3 to ~10 minutes.
Removing the package resolves the issue.
Do you want me to provide a log or something? Or is Microsoft.Net.Compilers supposed to work slower ?
@agocke @jaredpar Any idea what might be causing this? ngen or something?
Moving to the NuGet package can cause a slow down but it's usually on the order of 1-3 seconds due to the lack of NGEN on the initial compilation. A slow down of this magnitude means that very likely the compilation server is not being used.
Can you do the following:
My guess is that you're not going to see tihs process and instead see csc actively taking CPU.
Marking blocked pending a response from @sztrzask
@jardepar - I've done what you asked and yup, there is a lot of csc processes taking CPU.
Great. Well not great but at least that means we know what the issue is. 馃槙
What's happening is the MSBuild property UseSharedCompilation is being set to false. As such we are not using the compiler server and you're paying the JIT cost for CSC on every build. That is the reason for the slow down.
If you have a global porject include then you can set that value to true and it should fix the issue.
This doesn't appear to be applied to the latest stable nuget package (1.3.2 as of this time). Is there any chance this can get applied to stable?
@flaub this change was done in the 2.0 branch and won't appear in the 1.3.2 packages. If you are already usipng the NuGet can you update to the 2.0 RC? That will have the change.
After reviewing the commit, I'm wondering if this change will work when using csc.exe directly from the command-line (outside of MSBuild)?
@flaub no. The change is about using MSBuild as a driver of the compiler server. The command line compiler by default is unaffected by this change.
The command line compiler does have the /server option for opportunistically connecting to a running server. This requires a bit of setup though to get the benefits. The MSBuild task we author takes care of all the messy details of staarting and managing the server automatically.
Ok, thanks for the information. Just curious, but could you point me to the code that deals with these messy details?
@flaub may want to sit down before reading 馃槃
Thanks a lot, I think I just stumbled upon some of this. Appreciate it :)
Just come across this same issue, however when I set UseSharedCompilation to "true" my build fails when it encounters a C# 6 feature (e.g nameof). Leaving this property un-set fixes the build, except it starts taking ~twice as long again.
I'm referencing v 1.3.2 of the Microsoft.Net.Compilers package and I'm setting the property using the "MSBuild Arguments" property in my XAML build process.
@JustinPealing can you post the errors that you are seeing?
AddImage\AddImageCommand.cs (54): The name 'nameof' does not exist in the current context
Exception Message: MSBuild error 1 has ended this build. You can find more specific information about the cause of this error in above messages. (type BuildProcessTerminateException)
Exception Stack Trace: at System.Activities.Statements.Throw.Execute(CodeActivityContext context)
at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager)
at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)
@JustinPealing that looks like a valid error message from the compiler. Have you looked through the log and seen if an older versino of csc is getting used? Or if that use of nameof is as a variable vs. an operator?
How do I tell if an older version of csc is getting used from the logs? I'm pretty convinced that's the reason why its breaking, I just don't understand why using /p:UseSharedCompilation=true would cause this.
@JustinPealing You should have a list of csc.exe commands in the MSBuild log. Based on that error it sounds like your build is falling back to the legacy csc.exe that's in the framework directory (C:\Windows\Microsoft.NET\Framework...). It would be interesting if that shows up in your build log as well.
Okay, so I can see in the log files its using C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Csc.exe when /p:UseSharedCompilation=true is set. When this property is removed it uses E:\BuildWorking\Tfs Project\Build\src\Project\packages\Microsoft.Net.Compilers.1.3.2\build\..\tools\csc.exe.
I can reproduce this behaviour locally (the build passes as I have VS2017 installed, but I can see in the logs that its using the globally installed csc.exe instance).
What should I be seeing?
Okay, I think this is something to do with the way TFS chooses the MSBuild path. We are planning on moving away from XAML builds shortly, so I'm going to just live with the slow builds for now.
Thanks to @sztrzask for writing this up. This helped us reduce our build times from 4 minutes to 1 minute.