This discussion only applies to Assembly.Load().

Today CLR's assemblies loading mechanism is very dynamic. The dynamic nature is shown in various places:

1. Dependencies are not resolved until they are actually used.
2. You can subscribe to AssemblyResolve event to extend fusion probing logic.
3. You can even change current AppDomain’s settings to affect how fusion will probe for assemblies, or how fusion will return the result. 

The dynamic nature of CLR assemblies loading is really powerful. It gives the developers the freedom to return the assemblies from anywhere they want.

But on the other hand, the dynamic nature is directly at odds with performance. It is nearly impossible to do any performance optimization given today’s assembly loading mechanism.

For example, on a steady state machine, when there are two AppDomains with identical settings, in theory it should be OK to share the binding decisions between the two AppDomains.

But this is not possible today. Because,

1. Until the assembly is actually loaded, you can’t really tell where the assembly will be returned.
2. Between the AppDomain start and the actual assembly loading, user may have changed some AppDomain settings so the two AppDomains are not identitcal anymore.
3. Even user does not change AppDomain settings, between the AppDomain start and the actual assembly loading, the machine state may have been changed. For example, assemblies may have been installed/uninstalled from GAC.

All these problems won’t exist if assembly loading is static (Eager dependencies resolve, no AssemblyResolve hook, can’t change AppDomain settings.) You can even imagine that we can build some cache system that we won’t actually do any probing for assembly loading.

But of course, until the loading model is changed, the super fast probing system will always be a dream in the future.