Sunday, September 30, 2007

In Pex, we have our own version of all (and more) collection classes from the BCL. This duplication may sound stupid but there's a very good reason behind it: since Pex instruments code (i.e. rewrites IL), the BCL collections might be instrumented as well... leading to a poorer performance (instrumented code is slower for many reasons). Therefore, to avoid this situation, we ended up using our own implementation which never gets instrumented.

While using our collections, we added 2 features that we like a lot: readonly interfaces and small collections.

Readonly interfaces

Readonly interfaces are handy to 'safely' expose collections, once you start using them you get hooked:

  • ICountable<T>, a readonly enumerable with a Count.
interface ICountable<T> : IEnumerable<T>
{
    int Count {get;}
}
  • ICopyable<T>, a countable that can be copied around,
interface ICopyable<T> : ICountable<T>
{
    void CopyTo(T[] array, int index);
}
  • IIndexable<T>, a indexed collection
interface IIndexable<T> :  ICopyable<T>
{
    T this[int index] { get; }
}

We also have a couple more interfaces for dictionary style collections but you get the idea.

Small Collections

Small collections are optimized collections with 0, 1 or 2 elements. Depending on your scenario, these can improve the performance of your application while lowering the pressure on the GC (create less objects -> less stuff to garbage collect). If you create a lot of objects which each have collections, ask yourself: are you lazy allocating the collections? what should be the initial size of the collection? do you expect more than one element on average?

Comments are closed.