In our automated testes, we usually have a single place that sets up a configured in-memory Raven database which might look something like this:
public static EmbeddableDocumentStore CreateDocumentStore(Assembly assembly)
{
var store = new EmbeddableDocumentStore())
store.UseEmbeddedHttpServer = false;
store.RunInMemory = true;
store.Initialize();
IndexCreation.CreateIndexes(assembly, store);
return store;
}
Over time, I noticed that our tests were geting slower and slower. Turned out that the IndexCreation process, which uses code generation underneath the hood, is a slow process that adds ~70 milliseconds per index per test. Multiply that by 10s of indexes and 1000s of tests and you've got quite a performance hit both on single test runs and test sessions (CI / NCrunch / Mightymoose / R# Test Session etc).
To improve the perfromance of this I removed "IndexCreation.CreateIndexes(assembly, store);" and made it such that we only put the exact index definitions that a test needs into the document store using a predicate. Thus minimising the document store creation time for an individul test.
But I think we can do better...
When running multiple tests in a session, we are often re-creating the same index over-and-over. Or rather, raven is emiting the same code, compiling and loading the same named type over-and-over. Adding a static Dictionary<string, Type> to the static Compile() method improved the performance of provisioning an embedable document store on second and subsequent test runs (if those tests used the same indexes) by at least a factor of 10. That is, second test (that used 2 indexes) run times went from >200ms to ~20ms. This also reduces the impact of a developer failing to properly restricted which indexes are created in a test.
(Side note: A positive side effect of this optimisation is reduced memory usage that is 'leaked' when dynamically loading assemblies.)
While there are probably going to be issues over my implementation hack of a compiled type cache (thread safety for one), I am going to try to get this improvement, or something similar, officially supported.
Update: Well that was quick. The optimization has been added to RavenDB and will be available in a build soon. Apparently it knocked 5-7 mins of Raven's build time. :)