3

I have a relatively large winforms application written in C# .NET 2.0 using Visual Studio 2005. It also uses Crystal Reports. The compiled EXE is ~12 MB. The source code is ~60 MB.

The overall structure of the application is pretty simple. There is a single SQL Server database behind. The main form of the application doesn't do anything, except it hosts a menu with many items. Most of the menu items open up some non-modal form. Most of these forms are independent. Some forms contain "reports" - a read-only view of some data with a few parameters that user can change and refresh the report. Some forms provide an editable view of data. Essentially it is a DataGridView(s) with parameters to filter/limit what is shown and with buttons to add/edit/delete a row. Usually the grid itself is read-only. An Add/Edit command usually opens up a separate modal form with the list of fields from the selected row to edit.

There are ~250 forms in total in the application.

All source code is in the single solution and there is single project in the solution. There are few folders that group the source code of some forms together logically. Say, Sales, Finance, BizDev, etc.

The problem that I face is that if I make any slightest change in any file C# compiler recompiles everything. For example, if I change one line in one file and do "build solution" it takes 35 seconds to compile. If I do "clean solution" and then "rebuild solution" it still takes same 35 seconds to compile. The computer has 16Gb of memory, SSD disk and Intel Core i7, so there is not much room in improving the hardware. I tried to create a RAM drive and put the source code there. It didn't affect compile time at all. Most likely, these 60MB of source code are all in the Windows cache anyway with 16 GB of memory. In C++ world C++ compiler recompiles only the file(s) that is changed, but C# recompiles everything. Also, it uses only one core of the CPU out of 8. Also, the Visual Studio itself can't be used during C# compile time. In my case after I press F7 the VS code editor becomes extremely unresponsive. As I try to move the cursor around the code while the compiler is running it can take seconds to move from one line to another. I'm not even typing anything, just moving the cursor around to review the code.

My question is: if I somehow break this monolithic project into several smaller projects by simply moving logically related forms into separate projects, would it decrease compile time? As most of these 250 forms are independent it should be possible to NOT compile all of them when only one of them changes.

What would be the best approach to structure the whole thing in Visual Studio if my primary goal is to reduce everyday compile time?

UPDATE: Just to clarify, I use the term "solution" for SLN file and "project" for CSPROJ file.

I should have mentioned it at the start. When I was searching the web for "how to speed up C# compilation" I came across a lot of posts where people had solutions with many projects in them (70-100). Quite often in such cases it was recommended to reduce the number of projects. Also, there were some recommendations about specific project settings and how they affected the compiler performance. Seeing such problems with other people made me think that having many projects introduces significant overhead to compilation and general VS IDE performance.

Here I have an opposite situation. I have only one project in one solution. Having C++ background it looks very strange to me that C# compiler has to recompile everything every time. I hope that there exists some balanced approach that would allow C# compiler to compile only those files that have changed, thus reducing compilation time in everyday development when I focus on a small part of the whole project.

At the moment the project compiles without warnings.

If you say (from your experience) that C# compiler in VS2013 supports incremental compilation out of the box, I would consider switching from VS2005. If you say (again, from your experience) that indeed having 10 independent projects plus 1 main project for the main form in one solution instead of 1 big project in one solution would usually result in recompiling only two small projects, I would give it a try. If I follow this path of splitting the code into smaller projects I would like to know what are the "gotchas"/some obscure settings to look for, so that the VS and compiler performance would not become worse. Also, I would appreciate if you could highlight the best approach to configuring the whole solution in VS. For example, should all these small projects compile into a single big EXE, or each small project should compile into a separate DLL and instead of one big EXE I would end up with a dozen DLLs and a small EXE? I don't even know if both of these options are possible. Maybe there are other options.

I would appreciate your ideas.

Thank you.

Vladimir Baranov
  • 31,799
  • 5
  • 53
  • 90
  • Is it possible to upgrade to VS2013? It may have better performance. You could try with the free version as a test. But yes, splitting into projects should help. – Blorgbeard Nov 19 '14 at 02:37
  • @Blorgbeard: switching to the latest Visual Studio is a whole new project. I don't really know how difficult it could be. My gut feeling is that most problems would be with the Crystal Reports. At the moment I can't spend even a day trying to compile the project in new VS if I'm not sure that it would improve compilation time. – Vladimir Baranov Nov 19 '14 at 03:30
  • @RonaldEstacion: I'm not sure that I understood your comment correctly. In my case there is one solution, one project, one assembly, one EXE. I would like to learn how to restructure this to make incremental compilation possible. – Vladimir Baranov Nov 19 '14 at 03:33
  • http://stackoverflow.com/questions/222827/how-do-you-organize-your-version-control-repository outlines build process organization best practices. – ivan_pozdeev Nov 19 '14 at 13:01

2 Answers2

3

Firstly 35secs is not that long for a compile of a "large" project. The projects and files in those projects shouldn't be about minimizing compile time, it should be about packaging and managing dependencies.

Compile times depend on a lot of things.

Solutions with multiple projects can skip the compilation of projects when nothing has changed, however if you change code in a project early in the build order, it can trigger a recompilation of everything. Meaning in some situations compile times could be quicker, in others they might be slower.

If you have a lot of code that is rarely changed one sure way that definitely works is to move that code into a separate solution and as part of the compilation process copy the output DLLs of the solution to a staging area. You can then create file references to those DLLs from that staging area on the file system. When doing this I reference files from mapped network drive or from a drive created with a Subst command. The reason for doing this is to give you the flexibility of changing where your solution is picking up DLLs from easily by remapping the drive to another location.

Furthermore, I would look at separating out business logic from the forms, and putting that business logic into separate projects. Well designed applications usually incorporate an N-Tier design that would logically lend itself to having at least one (usually several) separate projects for each tier of the application.

Mick
  • 6,527
  • 4
  • 52
  • 67
  • redesigning this application to multi-tier is beyond my scope at the moment. I'm not familiar with assemblies, solutions, projects and I really need to know the basic principles behind them. It is easy to google for answers for a specific problem, but hard for general/basic/foundation principles. Say, I identified 20 out of 250 forms that are logically related. Let's assume that they are all invoked from the menu in the main form. Should I put them into a separate project in the same solution which has a main form? Should I put them in a second completely separate solution? – Vladimir Baranov Nov 19 '14 at 06:44
  • Second question. Say, I repeat the splitting process described above for another ~20 forms and so on and end up with, say, 10 projects (or solutions) plus 1 main project or solution with the main form. I expect that the main solution or project would always recompile, but if I make changes in a file in another project only that project and the main project would recompile. And I expect that time to recompile two small projects would be much less than 35 seconds it takes to rebuild everything. And I expect that it would take same 35 seconds to rebuild all. Are my expectations valid? – Vladimir Baranov Nov 19 '14 at 06:55
  • It's hard to say. I'd hazard a guess and suggest if your only goal is to lower the compile time from 35 secs, you might be disappointed with this venture. I don't actually think 35secs is a major problem. I've encountered projects which had solutions which took 45 minutes just to load, and about 20mins to compile. My suggestion, if you're that worried about compile time, create new code in separate solution, incorporate it into the main solution when it's ready. Or create a unit test project. – Mick Nov 19 '14 at 23:32
  • If I leave everything as it is these 35 seconds will only grow. It may be acceptable to spend 20 minutes to rebuild all, but then spend only 10 seconds to compile it again when one file changes. I guess, my question evolves into: how to do incremental compilation with C#. So, you suggest to split one solution into several solutions, rather than having one solution and several projects within these solutions. From this I deduce that C# would always recompile everything inside the solution, regardless of how many projects the solution has. Did I understand you correctly? – Vladimir Baranov Nov 20 '14 at 01:32
  • Using file references instead of project references means you reference statically compiled dlls. I've only used this approach on huge projects where there were hundreds of projects involved. I think at the end of the day you're just going to have to try it and see how it turns out. If you're after a guarentee its going to be faster no one is going to give you that, it could easily be slower. – Mick Nov 20 '14 at 13:23
  • I'll say it again, what you're doing is not normal. There are many reasons for having multiple projects in a solution for an application, I've never heard of improving compilation time being one of those reasons. I'm going to end this discussion here. – Mick Nov 20 '14 at 13:25
-1

Yes, it is always safe to have the project grouped logically. Anyway there are other factors that effect the compilation time.

Some points to improve compilation time. When you are not ready to deploy yet

1. If you have a setup project, do not enable the setup project unless you are ready to deploy / publish.

2. Look for warnings in the output window, the less number of warnings the better.

3. When working on one piece of code, exclude the irrelevant forms/projects/files that do not effect the current code

Rama Kathare
  • 920
  • 9
  • 29