Static CA makes solution build mutch slower. In my case > 2x slower than without CA. We can disable it but that is bad decision to lose its power. So what can we do?
First lets see how CA works.
You build solution. At each project build after msbuild Compile target fxcopcmd.exe is called with paths to assemblies which should be analyzed. fxcopcmd. generates CA xml log which is used by VS (or maybe output stream). fxcopcmd.exe loads assemblies(fast) and analyzing its synchronously, so only one CPU is loaded and 3 (in my case) are doing nothing. Only after CA is finished the next project in project dependency chain is builded.
So the weak place in CA were we can improve it - to force it work in parallel to use all CPUs.
I see such solution
To make fake fxcopcmd.exe that will take parameters from MSBUILD, remember it and instantly report to msbuild that all is ok and there were no error(through CA xml.log, or succeeded file, or maybe stream..). So MSBUILD will build the next project and at that time we will call real fxcopcmd.exe with saved parameters... if MSBUILD will call fxcopcmd.exe on next project - we will call one more time fxcopcmd.exe... so there will be few processes which will load all CPU'S. After real fxcopcmd.exe will finished we can call our MSBUILD target which will call only CA target from microsoft.common.targtets with out compiling and our fake fxcopcmd.exe will instantly reporting results (CA is finished at that time and we have log) to MSBUILD-VS.
What do you think? Will this speed up CA? Why Microsoft didn't make such staff and use only one CPU in CA?
I've once asked a similar question on Connect and got a reply directly from the team. At the ALM Summit in 2012 I discussed the topic and there were a number of reasons (in no particular order)
As you can see here in this MSDN forum post, Fxcop itself already uses multiple threads and (at least in the rules that shipped with 2010) there are a few issues with concurrency already that cause us to turn off concurrency for Fxcop in certain cases. If you want fxcop to use more (or fewer) threads, you can edit the fxcopcmd.exe.config
file:
<FxCopEngineSettings Version="1.32">
<Engines>
<Engine Name="Introspection" Enabled="True">
<!-- Change this number to use more (or fewer) threads -->
<Threading Count="1" />
<EnableFlowAnalysis>True</EnableFlowAnalysis>
</Engine>
</Engines>
</FxCopEngineSettings>
Though the forum post mentions Visual Studio 2008, I have applied this to fix issues with 2010 as well.
A much simplest way to make FxCop more efficient is to call it once after all projects have been compiled. This will cause it to only load all symbols and referenced assemblies once and will allow the engine to make maximum use of parallelism. There are some issues with this as well when you have a solution that mixes multiple target platforms and cpu's or when you want to use different .rules files for different projects.
Or you could do the same thing I do, which is to configure FxCop for your local solution, but not set it to run on each build. Then in Team Foundation Server Team Build (or any other build server you might use), override the configuration for FxCop to run "Always". That way you have no performance impact while building your local solution. It still allows you to run Code Analysis for your whole solution locally (from the Analyze menu item) and the automated build can guard you against checking in code with issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With