Perf trade off: lots of small assemblies or fewer bigger assemblies??


Over the internal CLR perf alias someone asked about what yields better performance having lots of small assemblies or a few of big ones…  I thought I’d you’d find the comments from the team interesting…


 


As Rico would say, nothing is 100%, you have to measure, but the census of the CLR perf folks is that fewer bigger assemblies are better.


 


Lot of assemblies in the managed world is bad for the same reason lot of dlls are bad in the unmanaged world. The OS has a per-dll cost which is reduced by combining assemblies.  In addition, inlining can be more aggressive within an assembly


 


The biggest reason that assemblies are expensive is because we try very hard to make everything else ‘light’.  Thus we try to push everything that can be shared to the assembly level that we can (thus it is shared among all classes in the assembly).    Similarly, we try to optimize class loading at the expense of assembly loading, since we expect more class loads.  If you have lots of small assemblies, you ruin this heuristic. 


 


Assemblies are also the unit of enforcing security.   Thus when doing cross assembly calls inlining is more constrained.   


You are also fighting the OS heuristics.   The File system is very good at prefetching data that is contiguous, however if you have lots of DLLs, they are not likely contiguous, which means disk moves, and significant loss of startup time. 


 


Also, because of compatibility issues, changing assembly boundaries is painful.   Thus it is worth some time ‘up front’ to insure that you can live with your present setup for a very long time. 

Comments (16)

  1. Paul Tyng says:

    Would there ever be a point where your working set size actually slows performance due to the amount loaded in which smaller assemblies would win out?

    Also another question / comment:

    In visual studio I find myself breaking out my functionality in to namespaces modeling the .Net framework ones (ie, collections, data, etc.). But I’ve also gotten in to the habit of breaking out my namespaces in to seperate assemblies so that I can utilize them in other solutions as well. Ideally all that I really need is a shared codebase and just share it between solutions since chances are they will be deployed with different versions of the shared assembly.

    So what I’m curiuos about is do you think there it would be beneficial to still have project seperation in Visual Studio (ie, I have a Company.Collections project with all my collection code) but then have the solution compile in to a single assembly? That way I can get the performance benefits, but still have the project as unit of code thats shared between multiple solutions. What I fear is having to share the actual files from within sourcesafe in order to trim down my number of projects.

  2. Joel Dolisy says:

    Tools like VS.Net force you into the multiple assemblies scenario by the way they organize projects.

    It would be good option of to be able to build one assembly out of multiple projects. I’m currious if you guys at MS use VS.Net for organizing your assemblies and builds?

  3. Charlie Hensler says:

    Here’s a related issue:

    I’m working in an environment where there are a lot of small web applications, done in both ASP an Cold Fusion, and where we are now moving to .NET, and implementing a build environment, including source control).

    Traditionally, they have generally used very few vdirs, and placed an app’s files in a sub directory under an existing vdir.

    In .NET however, this doesn’t really work, since we’re no longer dealing with files and script, but with compiled code and the VS solution/project system. I guess the .NET corollary would be a single web project with unrelated "apps" divided up into folders, then compiled into one large .dll.

    This seems less than ideal – for a simple change it would mean recompiling the entire "project", and redeploying the entire thing (including the huge dll). I shudder at the thought of artificially coupling a bunch of unrelated functionality in this way.

    The alternative (which I prefer) seems to be to accept an increased number of vdirs containing individual apps (although I did find I could compile separate projects, but then deploy to a single vdir – just by deploying the separate .dll’s to the vdir’s bin folder. I decided against this though because it creates an odd deployment scenario).

    I have no problem with many vdir’s, but culturally here they don’t like that idea (not exactly sure why not). The fundamental issue is moving from a scripted ASP environment (where a change to a single page can be made without a compile), to a (much better overall) platform where there is a compiled component.

    Any thoughts?

  4. milbertus says:

    Paul, one somewhat hacky solution to your problem is to link files in VS. When you add a file to a project, instead of clicking the Open button in the dialog, click the drop down arrow next to it, and select "Link File" (or something like that). Then, the file is still added to the project, however it won’t be copied to the project’s location, allowing the same physical file to be shared between projects.

  5. Jiho Han says:

    Paul,

    I remeber there being a way to package multiple assemblies into a single assebly at deployment time. As I understood, you couldn’t do this from VS.NET IDE but only using the SDK command line tools. That also goes for building your projects to a .netmodule instead of .dlls. VS.NET 2003 – as far as I know – doesn’t support this.

    I wonder whether whidbey addresses this problem…

  6. Jeremy Marsch says:

    What constitutes "lots" of assemblies? 5? 10? 100?

  7. Naveen Karamchetti says:

    I guess 10+ would mean lots of assemblies.

  8. I've been hearing from several colleagues about how their Visual Studio solution files have many