Collections and threadsafety (with some perf implications)

I've already made the design decision that my collections will not be inherently threadsafe.  If you want to use them you will need to provide your own locking mechanism to ensure that multiple threads don't cause a problem.  However, i do believe that there should be no issues using my collections from a pure readers persepective.  I.e. no matter how many threads you have, as long as they do not change state it should be safe to share the collection.

However, it's unclear to me how to mark mark something as having that invariant (or whether i should mark it at all).  C++ gives this to you with the const modifier on a method.  I.e. i could mark my Empty property “const” meaning that it was allowable to query an immutable version of that object for that property.  Unfortunately, i don't know if I'm safe adding that invariant to the interface.  What if i have a collection that lazily initializes it's fields.  Then calling Empty on it might actually affect state.  Should the interface place these sorts of invariants on the implementation?  Or should I leave that up the the implementing classes and tell consumers of the interface that all thread safety (including multiple readers) is up to them?

Another issue comes up regarding threads and performance.  Lets take a look at my implementation of ArrayCollection.Add again:

        public virtual bool Add(A element) {

            //From CLR 369 (Dynamic Tables)

            if (array.Length == 0) {

     array = new A[1];

            }

            if (count == array.Length) {

                A[] doubledArray = new A[count * 2];

                Array.Copy(array, doubledArray, count);

                array = doubledArray;

            }

            array[count] = element;

            count++;

            //Adding an element always modifies an ArrayCollection

            return true;

        }

 

Here we can see that I access the field “count” 5 different times. However, with each access the runtime is going to have to do a memory read in order to make sure it has the up to date count value in case another thread modified it. However, i already said that I don't care about my collection being thread safe. So i would actually not want the runtime to do this check. Instead, I would like the jitter to access the “count” field once and then use that value in all the places where “count” is read. (similaryly i would like to do the same with “array“) I could do this in the following manner:

 

public virtual bool Add(A element) {

int _count = count;

//From CLR 369 (Dynamic Tables)

if (array.Length == 0) {

array = new A[1];

}

if (_count == array.Length) {

A[] doubledArray = new A[_count * 2];

Array.Copy(array, doubledArray, _count);

array = doubledArray;

}

array[_count] = element;

count = _count + 1;

//Adding an element always modifies an ArrayCollection

return true;

}

 

However, this clutters up the code immensely, adds more opportunity for errors, and would be an example of premature optimization since i have no data to indicate that accessing “count” is actually a costly operation. However, it is something to consider in the future.