Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Can NCrunch be improved in the "analyze stage" somehow?
GreenMoose
#1 Posted : Thursday, November 5, 2015 3:06:03 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 507

Thanks: 145 times
Was thanked: 66 time(s) in 64 post(s)
Hi.

I have been wondering why NCrunch takes so long for "building/processing" so I set up a simple test and it seems the pure compile time seems to be about the same as e.g. ReSharper (13s) but then NCrunch jumps into analyzing stage so total it takes about 27s when I use static analysis (NUnit), no matter if I have "Analyse line execution times" enabled or not for the test project, and total 50s when using dynamic analysis (which is a pain when trying to do TDD off course).
This is on 1 test project we have in the solution (we have a couple of smaller test projects going considerably faster).

Can’t this processing be made multi-threaded in some way so the BuildHost/TestHost processes consume more CPU and thus complete faster?
Can I do anything with respect to settings / OS to speed up this process for this particular project? (workspace is on RAMdisk, snapshot on SSD).

Thanks.
nrjohnstone
#2 Posted : Thursday, November 5, 2015 7:48:16 PM(UTC)
Rank: Member

Groups: Registered
Joined: 7/1/2015(UTC)
Posts: 12
Location: New Zealand

Thanks: 1 times
Was thanked: 2 time(s) in 2 post(s)
I think this has something to do with the way that in order to find out all of the test case names, all instances where you use TestCase or TestCaseSource are executed to find out the names, even if you are only running a single test from a different fixture that does not have a test case !

At least, this seems to be what happens when I stick some debug breakpoints in all the test case sources in our test project, then run a single test in debug mode.

Remco should be able to confirm
Remco
#3 Posted : Thursday, November 5, 2015 10:24:15 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Hi,

Those are some fairly extreme times for a single project. How large is this project?

Broadly, there are two things that happen in the analysis step that could take a long time:

1. The creation of an application domain for discovery and testing: Before NCrunch can invoke a test framework to discover tests, it needs to first build an application domain that can host the test assembly and anything it references. This includes loading the test assembly into the application domain, passing it through the JIT, loading referenced assemblies, etc. The time taken for this is highly dependent on the amount of code required in the test domain. If you have references to very large assemblies (such as entity framework), this can add considerable time to the analysis step. None of the effort here is wasted - NCrunch will re-use the same process and application domain for executing the tests when this happens later. So we're basically bringing a whole lot of work from the test run forward into the analysis step.

2. The physical discovery of tests (via NUnit in this case?): Inside the above application domain, NCrunch will load and invoke NUnit to discover tests in the test assembly. Because it was designed as an end-to-end test runner, NUnit was never optimised to be used in this way. It enumerates the assembly using reflection and provides the test data to NCrunch. Because NUnit is responsible for the heavy lifting in the discovery process, there are no opportunities for optimisation here other than switching the framework utilisation type to 'StaticAnalysis' so NCrunch can do this work using metadata instead.

The first thing I would recommend if you want to improve your build/discovery times on a test project this size is to look at breaking up the project. NCrunch has no way to selectively build different parts of a project, and the discovery step is always assembly-wide. By having a number of smaller projects instead of one big one, you can greatly reduce the build and discovery times as NCrunch will have more opportunity to only build the areas of code that have actually changed.

Changing your framework utilisation type for NUnit to 'StaticAnalysis' may make some difference, but you'll take a huge hit here in compatibility with tests using TestCaseSource etc, so this may not be worth it.
GreenMoose
#4 Posted : Friday, November 6, 2015 8:37:53 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 507

Thanks: 145 times
Was thanked: 66 time(s) in 64 post(s)
Remco;7947 wrote:

Those are some fairly extreme times for a single project. How large is this project?

1 213 files, and (according to NCrunch Metrics) Code Lines 172 030 Compiled Lines 68 870

Remco;7947 wrote:

Because NUnit is responsible for the heavy lifting in the discovery process, there are no opportunities for optimisation here other than switching the framework utilisation type to 'StaticAnalysis' so NCrunch can do this work using metadata instead.

Ok that's a pity, do you know if this performs better with e.g. xUnit or are basically all test frameworks the same with respect to the performance during the "analyse stage" ?

Remco;7947 wrote:

The first thing I would recommend if you want to improve your build/discovery times on a test project this size is to look at breaking up the project.


Yeah this is an ongoing work, which itself leads me to another perf problems. Since mosts tests involve NHibernate each NCrunch test host must fire up a static NH Session factory which takes about 10s, so the more projects I introduce the more test runners I must allow to sit idle to be able to reuse as many as possible to avoid this 10s overhead. Now I have set this figure to 15.
(I am not sure when actually the test host can be reused though, they seem to start quite often according to process explorer anyhow)

Thanks.
Remco
#5 Posted : Friday, November 6, 2015 10:19:38 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
That's definitely on the extreme side for project size. I can understand the issue you have with the session factory initialisation, and this is tough to work around for best performance. The only suggestion I can offer here would be to look at ways that you might be able to move some of the code out of the giant project without needing to move the tests themselves, but this is likely to be particularly challenging and I don't doubt you've already considered it as an option.

I don't yet have any hard data on which frameworks perform better on the analysis step vs others, as this can be extremely variable depending on the solution/projects involved. My best guess would be that MSTest is fastest, as this is the framework NCrunch has the best control over during both discovery and execution. NUnit's static analysis should be very fast under NCrunch, as the static analysis is performed by NCrunch itself rather than NUnit. Both versions of Xunit operate on the same principles as NUnit, so any difference here would be down to the internals.

Currently under development in NCrunch is a feature intended to track the responsiveness of the engine across its various tasks (build, analyse, test, distribute, etc), and provide a consolidated per-test report on where the time is being spent. I think this should really help to give good visibility on what the engine is doing and where the bottlenecks are. It may also be useful to track the performance of the individual test frameworks to identify their various strengths in a real-world environment.
Remco
#6 Posted : Wednesday, December 16, 2015 3:18:57 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
The just-released NCrunch 2.19 includes several improvements targeting the performance of the analysis step - http://www.ncrunch.net/download.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.054 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download