tags:

views:

116

answers:

6

I can understand an added cost at application startup of loading a separate DLL, but is there an overhead when referencing code in a separate library?

Say I have my application (be it ASP.NET WebForms, MVC or WinForms) and I decide for one reason or another that from a maintenance standpoint, it's better to have a couple of classes moved out to their own separate library so that I can float other applications on top of it some time down the road.

Is there any increased overhead in referencing the classes in the separated library than if I'd kept them inside my main application and referenced them there? I want to move them out, but the application has a potential requirement for a huge amount of scaling, so I don't want to shoot myself in the foot by doing this.

Normally I would move the code out to it's own library without giving it a second thought, but usually I'm not writing applications that need the level of scaling required for this one and so I'm now second guessing myself.

+7  A: 

If it makes sense from an API design / code clarity / maintenance point of view -- do it!

A faster processor is cheaper than a programmer who has to maintain a Big Ball of Mud.

dtb
I agree with the sentiment in theory - but lets say we're scaling an application up from tens or hundreds of users to hundreds of thousands of users or even millions of users, what then?
BobTheBuilder
Loading an assembly is usually a one-time operation. Once it's loaded for the first user, it won't have to be loaded for the following 999,999 users.
dtb
@BobTheBuilder: let me change it up, why not start with the more maintainable solution first, and if you recognize a performance penalty, simply move the code into a single project rather than multiple class libraries.
sixlettervariables
@dtb - thanks, that's the info I was looking for
BobTheBuilder
@sixlettervariables - I normally would, but the nature of the scalability requirements of this project has made me question many assumptions I would not normally give a second thought. I just don't want to do something now and kick myself for it later because of some assumption I should have questioned but didn't.
BobTheBuilder
The recommendation to prefer a small number of large assemblies over a large number of smaller assemblies still holds, of course. Don't create an assembly for each class.
dtb
@BobTheBuilder I'm with @6letter and @dtb - start with maintainability, even at 40,000 requests/second (I own the MSN homepage - entirely C# page handler) loading assemblies on binding is the least of your worries.
stephbu
@stephbu Thanks - that input is valuable given your background.
BobTheBuilder
+3  A: 

There's an overhead for loading assemblies, so by moving types to new assemblies you introduce a delay. If you load many assemblies if will affect performance, but otherwise it is not a big problem in my experience.

Keep in mind that if you're using multiple AppDomains, there are two options for loading assemblies: Per AppDomain or domain neutral (i.e. shared between the AppDomains). If you load the same assemblies in several AppDomains you will have to pay the cost of loading these multiple times (and you will also have multiple copies of the assemblies in the process which in turn may also affect overall performance).

On the other hand, by moving useful types to assemblies you most likely make it easier to reuse those in other projects.

In my experience there is a measurable overhead, but unless you're sure this is the main source of any performance related issues your experiencing I would leave it alone. Assemblies should primarily make sense on the architectural level.

Brian Rasmussen
If all the assemblies are loaded initially at application start-up, is there a continued overhead (other than memory requirement) - i.e. an increased amount of instructions to call each method, or is the overhead complete once the assembly is initially loaded at application startup?
BobTheBuilder
...but conversely, of course, there's an overhead to loading a big assembly vs. a small one, so the difference between one big assembly vs. many small assemblies may not be clear-cut. As always with this kind of micro-optimisation, if it matters, *measure it*.
itowlson
When we're scaling up from hundreds of users to hundreds of thousands of users, will the overhead of the added DLL increase too or will it be the same for one user as it is for a hundred thousand users? It loads the library at startup and it's done?
BobTheBuilder
@otowlson - I'm not sure I know how to measure this... which is why I asked the question
BobTheBuilder
@BobTheBuilder: Once the assemblies are loaded there is no additional overhead when referencing the types AFAIK.
Brian Rasmussen
@itowlson: Good point and as Mark points out it is rarely the best way to optimize. Assemblies should make sense in their own right.
Brian Rasmussen
@Brian - Thanks, that's the info what I was looking for; If it's a one time hit rather than a hit per method call then I'm good to go
BobTheBuilder
+2  A: 

The only penalty you pay is the load time of that library whenever it is first used. Other than that, you don't need to worry about a performance penalty for splitting it out into another library. All libraries will get loaded into the same application domain by default. If you load them into different domains then you will experience some performance decrease when going across domains.

TskTsk
+3  A: 

If there's any overhead at all, it negligible (measured in nanoseconds).

In any case, scalability is not about squeezing out a few more nanoseconds here and there, but about whether you can handle an increase in application load by adding more machines (horizontal scalability) or more hardware (vertical scalability).

Do make your separate library - it will have no measurable impact on performance or scalability, but it will hopefully make the code more maintainable.

Mark Seemann
My experience tells me otherwise. Loading a lot of assemblies adds a significant overhead compared to loading the same code as few assemblies.
Brian Rasmussen
The number of instructions per call was more what I was worried about than the nanoseconds eked out of the system. By increasing the number of instructions per call, I'd max out the machine more quickly, which would lead to decreased user experience because the CPU is working harder than necessary, which uses more power etc. Think about the environmnent ;)
BobTheBuilder
@Brian Rasmussen: Agreed - loading the assemblies incurs a bit of an overhead, but some of it can be removed by putting the assemblies in the GAC. Once the assembly is loaded, however, I'm not aware of any significant overhead.
Mark Seemann
@BobTheBuilder: Even if there's a (measurable) overhead, it's going to be irrelevant compared with typical server application bottlenecks. I don't know which kind of application you are going to build, but if there's just one out-of-process invocation (database read or write, web service call, file I/O) you are going to feel that a lot more.
Mark Seemann
A: 

Although I don't have any stats to back it up, I don't believe that for user level applications(you did mention winforms) you'll notice any real performance degradation by separating some of your classes into different assemblies. You will probably spend most of your time in UI/web server/database land . . . If there not a 'feel-able' difference, then I'd move classes that are not used very often into separate assemblies and dynamically load them only when needed. You could drive this lazy load from app.config entries for maximum flexibility. Personally, I wouldn't bother with multiple-domain application models unless you needed to build a highly available or extensible application. This is no small undertaking, I can assure you! TheEruditeTroglodyte

TheEruditeTroglodyte
+1  A: 

Overall the biggest overhead with separate assemblies is the build time: the Visual Studio/Resharper combination works best with a small (< 15) number of assemblies.

Structure your code using namespaces. Organise your deployment using assemblies.

Tim Robinson