A legacy app I am working on currenty takes ~2hours to build. The project has about 170 projects with 150 or so being unmanaged C++ and the other 30 C#.Net 2.0.
What are some suggestions on ways to improve build times for something like this?
Focus on the C++ projects - they are almost guaranteed to be the largest time drains for building.
Some tips on getting the C++ build times down:
Make sure that you're only including headers that you need in the C++ projects!
Use forward declarations whenever possible in headers instead of including other headers
Use the /MP switch to build in parallel, when possible
Use abstraction effectively
Be sparing in the use of inline functions, since these cost more at compile time
Get the dependencies correct, so you're not building more often that required
Use pre-compiled headers appropriately
Aside from that, if you're talking 2 hour build times, often there is a simple, cheap (in a big picture way) solution, as well:
Upgrade your hardware to help reduce the computation times
If you install IncrediBuild on every machine that needs to build it, it distributes the build process among all of the machines.
If you really want to just throw hardware at the problem you can set up a few dedicated machines that serve only as IncrediBuild clients.
On a different scale, make sure your every project has pre-compiled headers configured correctly.
You may try the distributed build system Incredibuild: http://www.xoreax.com/visual_studio.htm
You could use a tool like lint to see if you have redundant include files in your c++ projects.
There is also a great article on this subject at Games from Within.
Make multiple solutions for the project that only include relevant subsets of the projects and leave one super solution for releases etc.
Related
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.
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.
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
The Windows Azure client libraries are very big (several MBs), and I have a fairly small project (on the order of a few hundred KBs) that uses only a few functions from them. Is there a way for me to link in those functions at build time, so that the resultant DLL doesn't get hugely bloated, and I don't have to link the functions in at runtime?
Something like this http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx, but I get the impression that bundles in the whole DLL.
Thanks!
Edit: Because there are external constraints on the size of the final deliverable DLL, inflating it this much is an absolute last resort - the only other option I'm aware of is just to duplicate the code I use verbatim.
In a word: No.
Remember that even though you only use a few functions, there are likely many other function in the library that those functions use, that you don't even know about!
You can't do this, because you don't have access to all the dependencies. Remember also that those dependencies may even reside in another DLL, and you need to include that entire DLL for the same reason.
What you are looking for sounds very like .NET Native.
Unfortunately for you, its only preview and right now works only with Store Apps for devices. Statements like this
We will continue to evolve and improve native compilation for the range of .NET applications
can be found on the internet but nothing specific about web apps\Azure.
Until then, answer is No
i'm working on a large c# project,i wonder why people use DLLs in their apps. I know that a dll file ( please correct if i'm wrong) contains some functions, but why don't we put those functions inside our main c# app?
Thanks
Most of it is summed up in the answer to this question, but the basic reasoning is "so you don't have to duplicate code".
Code reuse. Usually dll files contain functions that are useful in more than one app, and to have them in a single compiled file is a lot easier than copying over all that code.
Portability, Reusability, Modularity.
Splitting types and the like into separate assemblies allows you to reuse those types in different projects, maintain those types a modular fashion (e.g. update just one assembly instead of the whole app), and share parts of your code with others.
It also allows you to group common functionality into a single package.
Maintainability. When you need to fix a bug, you can release just the DLL containing the fix, instead of having to re-release the entire application.
This is an interesting question in a modern computing.
Back in the 16bit days DLLs cut down on the amount code in memory.
This was a big issue when 16 meg computers where considered fully loaded.
I find many of the answers interesting as though a DLL is the only way to have a reusable,maintainable and portable library.
Good reasons for dll's are that you want to share code with an external party.
Just as Visual Studio and other library vendors give you dll's this makes there code available to a external consumer. However, at one time they did distribute them in another way.
Patchable, This is true but how often does this really happen. Every company I've worked for has tested products as a unit. I suppose if you need to do incremental patching because of bandwidth or something this would be a reason.
As for all the other reasons including reusable, maintainable, modularity.
I guess most of you don't remember .LIB files which were statically linked libraries.
You can even distribute .LIB files but they have to be introduced at compile time and not runtime. They can help facilitate reusable, maintainable and modularity just like a DLL.
The big difference is that they are linked when the program is compiled not when it is executed.
I'm really beginning to wonder if we shouldn't return to .LIB files for many things and reducing the number of DLL files. Memory is plentiful and there is overhead in load time when you have to load and runtime link a bunch of DLL files.
Sadly, .LIB files are only an option if your a C++ guy. Maybe they will consider them with C# in the future. I"m just not sure the reasons for DLL's still exist in the broad context they are used for today.
In big softwares, you have many teams they work on several different modules of program, and thay can proceed their goals without needing to know what others is doing! So one of the best solutions, is that each team produces own codes in parallel. So,dll comes to scene....
Extensibility - a lot of plugin frameworks use DLLs/Assemblies for plugins.
dll : a dynamic link library :
it is a library.
It contain some functions and data.
Where we use these function?
we use these function and data which are inside the dll,in another application or program.
the most important thing is that dll will not get loaded into memory, when it require , called it is loaded into ram .
One of the best use is, one can integrate many third party functionalities into your application just by referencing the dlls, no need to use every third party tool/application into your system.
For example, you need to send a meeting invite via MS outlook through code, for this simply refer the dlls provided by MS outlook in your application and you can start coding your way to success!
I want very specific answer from the developers who did this and want to know how you resolved the problems you faced.
We have very big MFC (VC6) 32 bit application existing for 10 years. Now we would like to migrate it to .NET unmanaged 64-bit application. Here we have some problems, our UI should not change, we may need some managed .NET class for easier development, without affecting architecture how to add managed code with unmanaged code, lots win32 APIs might get changed to new APIs, should be run in XP, Vista, Windows 7 OS machine without any change, these activities should not be time consuming, new technologies analysis should be done as we are MFC programmers...
Pls share your experience and if you have any clear documents will be very helpful...
Note:
For the clear understanding, I am re-phrasing some points again. We want to migrate our VC6 native code 32-bit application to VS2008 (or VS2010) native code (unmanaged C++) with 64-bit support. The primary requirement is there should not be any change in existing UI. In Addition, if .NET supports the combination of managed code with unmanaged code, we can try using some features like .NET remoting in unmanaged C++ environment. And one more important thing I would like to convey to all is that we are not going to start any coding in C# or from scratch.
We've done this is steps (VC6 -> VS2005 -> VS2008 -> (soon) VS2010 ) and most issues were related to changes in the API.
unsafe string operations (strcpy vs. strcpy_s ) that give out a TON of warning messages (use the _CRT_SECURE_NO_WARNINGS preprocessor define to remove them if you do not want to fix them all )
Changed in prototypes for message handlers (returns LRESULT, changes in WPARAM and LPARAM, ... )
Deprecated API (you'll find them out soon enough, I think there's a page on msdn about that)
Compiler might be a bit more strict in regards to standard C++ .
It's hard to go to specifics...
but have a look at this blog entry for some more info : http://insidercoding.com/post/2008/08/20/Migrating-from-VC6-to-VC9.aspx
Good luck.
Max.
What you're asking for isn't really a migration -- it's a nearly complete rewrite, at least of the entire UI. Unless your "very big ... application" has a very small, simple UI, I'd sit back and think hard. Read Joel's Things You Should Never Do.
Bottom line: this is almost certainly a really bad idea. If you do it anyway, you need to start out aware that it will be quite time consuming.
If you decide to go ahead with this, you nearly need to do it incrementally. To do that, I'd probably start by finding discrete "pieces" of functionality in your existing code, and turning those pieces into ActiveX controls. Once you've gotten that to the point that your main program is basically a fairly minimal framework that most instantiates and uses ActiveX controls, it becomes fairly easy to create a new framework in managed code that does roughly the same thing, delegating most of the real work to the existing ActiveX controls. Once you've done that, you can start to migrate individual controls to managed code as you see fit.
The point of doing things this way is to avoid having a long interval during which you're just writing new code that duplicates the old code, but can't do any updates for your customers. Nearly the only reasonable alternative I've seen work reasonably well is to have two separate development teams: one continues to work on and update the old code base at the same time as the second team starts the total rewrite from the ground up. If you have enough money, that approach can work out quite well.
Microsoft, for one example, has done things like this a number of times. Just for a couple of examples, years ago when there were rumors that Borland (then Microsoft's biggest competitor in programming language tools) was going to produce a TurboBASIC, Microsoft decided QuickBASIC (V2 at the time) really couldn't compete. They responded by setting up two teams: one to do as much upgrading as reasonable to QuickBASIC 2 to produce QuickBASIC 3. The second team did a total rewrite from the ground up, producing what became QuickBASIC 4.
Another example is Windows 95/98/... vs. Windows NT. They continued development of the existing Windows code base at the same time as they did a total rewrite from the ground up to produce Windows NT. Though they kept the two teams synchronized so UIs looked similar and such, the two were developed almost entirely separately from each other. Only after years of overlap between the two did they finally quit working on the old code base (and I sometimes wonder whether the crappiness of Windows Me wasn't at least partly intentional, to more or less force users to migrate to the NT code base).
Unless you can do that, however, nearly your only chance of success is to use an incremental approach.
As Jerry has mentioned Joel talks about this in his blog Things You Should Never Do.
Moreover there are other things to be considered with this conversion.
What would you do with existing VC++ 6.0 code base.
Qualification time( different OS, SQL etc) needed to test the entire product after the changes are made.
How do you manage 2 code bases with and without 64 bit support.
PS: Most importantly by the time you fix and qualify your product in VS2010 i guess VS 2012 would have released :)
I often hear people praise the compilation speed of C#. So far I have only made a few tiny applications, and indeed I noticed that compilation was very fast. However, I was wondering if this still holds for large applications. Do big C# projects compile faster than C++ projects of a similar size?
Yes, C# normally compiles a lot faster. Not always fast enough though. My biggest C# codebase with maybe a million lines of code with lots of projects took about an hour to compile. But I suspect much of this time is due to visual studios poor build system.
Compile time for C++ on the other hand is usually much longer, but is also much more dependent on how you organize your code. Poor handling of header file dependencies can easily increase compilation time with several orders of magnitude.
C++ is so slow to compile as the header files have to be reread and reparse every time they are included. Due to the way “#defines” work, it is very hard for a compiler to automatically pre-compile all header files. (Modula-2 made a much better job of this) Having 100s of headers read for each C++ file that is compiled is normal on a lot of C++ projects.
Sometimes incremental c++ compiles can be a lot faster than C#. If you have all your C++ header files (and design) in a very good state (see books like Large-Scale C++ Software Design, Effective C++) You can make a change to the implementation of a class that is used by most of the system and only have one dll recompile.
As C# does not have separate header files whenever you change the implantation of a class, all uses of the class get recompiled even if the public interface of the class has not changed. This can be reduced in C# by using “interface based programming” and “dependency injection” etc. But it is still a pain.
However on the whole I find that C# compiles fast enough, but large C++ projects are so slow to compile that I find myself not wanting to add a methods to a “base class” due to the time of the rebuild.
Having lots of Visual Studio projects with a handful of classes in each can slow down C# builds a lot. Combining related projects together and then “trusting” the developers not to use class that are private to a namespace can at times have a great benefit. (nDepends can be used to check for people breaking the rules)
(When trying to speed up C++ compiles I have found FileMon very useful. One project I worked on, the STL was added to a header file and the build got a lot slower. Just adding STL to the precompiled header file made a big difference! Therefore track your build time and investigate when it gets slower)
As far as I can tell from my own experience, yes, C# compiles a lot faster than C++ projects. Even for large applications.
This can be explained by the fact that C# is less complicated as a language than C++, and that C# is translated to IL (which can be optimized and translated later on to machine code) and C++ is translated immediately to machine language.
It is also my observation that C# is significantly faster to compile than C++. One of the main reasons is of course templates that don't need to be in headers in C#, as there are no headers. But heavy use of templates (mostly any modern C++ library like Boost) is killing the compile time in C++.