Безопасность потоков для высокопроизводительного кэша в памяти

У меня есть статический кеш в памяти, который записывается только раз в час ( или дольше ), а читается многими потоков с чрезвычайно высокой скоростью .Общепринятая мудрость подсказывает, что я следую следующему шаблону:

public static class MyCache
{
    private static IDictionary<int, string> _cache;
    private static ReaderWriterLockSlim _sharedLock;

    static MyCache()
    {
        _cache = new Dictionary<int, string>();
        _sharedLock = new ReaderWriterLockSlim();
    }

    public static string GetData(int key)
    {
        _sharedLock.EnterReadLock();
        try
        {
            string returnValue;
            _cache.TryGetValue(key, out returnValue);
            return returnValue;
        }
        finally
        {
            _sharedLock.ExitReadLock();
        }
    }

    public static void AddData(int key, string data)
    {
        _sharedLock.EnterWriteLock();
        try
        {
            if (!_cache.ContainsKey(key))
                _cache.Add(key, data);
        }
        finally
        {
            _sharedLock.ExitWriteLock();
        }
    }
}

В качестве упражнения по микрооптимизации, как я могу избавиться от еще большего количества тиков при относительной стоимости общих блокировок чтения ? Время для записи может быть дорогостоящим, так как это случается редко. Мне нужно читать как можно быстрее. Могу ли я просто сбросить блокировку чтения (см. Ниже) и сохранить потокобезопасность в этом сценарии? Или есть версия без блокировки , которую я могу использовать? Я знаком с ограничением памяти, но не знаю, как безопасно применить его в данном случае.

Примечание: я не привязан ни к одному из шаблонов, поэтому любые предложения приветствуются, если конечный результат будет быстрее и в C # 4.x. *

public static class MyCache2
{
    private static IDictionary<int, string> _cache;
    private static object _fullLock;

    static MyCache2()
    {
        _cache = new Dictionary<int, string>();
        _fullLock = new object();
    }

    public static string GetData(int key)
    {
        //Note: There is no locking here... Is that ok?
        string returnValue;
        _cache.TryGetValue(key, out returnValue);
        return returnValue;
    }

    public static void AddData(int key, string data)
    {
        lock (_fullLock)
        {
            if (!_cache.ContainsKey(key))
                _cache.Add(key, data);
        }
    }
}
5
задан JoeGeeky 19 November 2011 в 16:12
поделиться