Compare performance of Concurrent Dictionary with Dictionary+Locks I wanted to measure the performance of Concurrent Dictionary vs Dictionary+Locks in a multithreaded environment. So I created my own SyncDict class of type&lt;int,int[]&gt;. Whenever there is a key match, it adds the int[] array value to itself, it also locks the whole dictionary with ReaderWriterLockSlim while updating the value.

I replicated the whole code through Concurrent Dictionary and I am using AddOrUpdate() method. 
Whole console app code can be found here https://dotnetfiddle.net/1kFbGy Just copy paste the code in console app to run. It will not run fiddle

After running both codes with the same inputs I see a considerable amount of difference in running time. For example for one particular run on my machine Concurrent dictionary took 4.5 seconds vs SyncDict took less than 1 second.  

I would like to know any thoughts / suggestions explaining the above running time. Is there anything wrong am I doing here?

 class SyncDict&lt;TKey&gt;
    {
        private ReaderWriterLockSlim cacheLock;
        private Dictionary&lt;TKey, int[]&gt; dictionary;
        public SyncDict()
        {
            cacheLock = new ReaderWriterLockSlim();
            dictionary = new Dictionary&lt;TKey, int[]&gt;();
        }

        public Dictionary&lt;TKey, int[]&gt; Dictionary
        {
            get { return dictionary; }
        }

        public int[] Read(TKey key)
        {
            cacheLock.EnterReadLock();
            try
            {
                return dictionary[key];
            }
            finally
            {
                cacheLock.ExitReadLock();
            }
        }

        public void Add(TKey key, int[] value)
        {
            cacheLock.EnterWriteLock();
            try
            {
                dictionary.Add(key, value);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }

        public AddOrUpdateStatus AddOrUpdate(TKey key, int[] value)
        {
            cacheLock.EnterUpgradeableReadLock();
            try
            {
                int[] result = null;
                if (dictionary.TryGetValue(key, out result))
                {
                    if (result == value)
                        return AddOrUpdateStatus.Unchanged;
                    else
                    {
                        cacheLock.EnterWriteLock();
                        try
                        {
                            Parallel.For(0, value.Length,
                            (i, state) =&gt;
                            {
                                result[i] = result[i] + value[i];
                            });
                        }
                        finally
                        {
                            cacheLock.ExitWriteLock();
                        }
                        return AddOrUpdateStatus.Updated;
                    }
                }
                else
                {
                    Add(key, value);
                    return AddOrUpdateStatus.Added;
                }
            }
            finally
            {
                cacheLock.ExitUpgradeableReadLock();
            }
        }

        public void Delete(TKey key)
        {
            cacheLock.EnterWriteLock();
            try
            {
                dictionary.Remove(key);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }

        public enum AddOrUpdateStatus
        {
            Added,
            Updated,
            Unchanged
        };
    }
Comparison


A comparison of performance of 2 classes only makes sense if both adhere to the same specification. Does your class do what a ConcurrentDictionary does?


Review


Why would you allow access to the underlying dictionary? If you must allow it, return a IReadOnlyDictionary.
Checking arguments before taking a lock prevents unnecessary locks on bad input.
AddOrUpdate does not work; have you checked  if (result == value)?


int[] a = new int[]{ 0, 1 }; 
int[] b = new int[]{ 0, 1 }; 
Console.WriteLine(a == b);  // False


Or is this as designed?


What is the purpose of this? What if both arrays have different size?



 Parallel.For(0, value.Length,
 (i, state) =&gt;
 {
     result[i] = result[i] + value[i];
 });