都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

.NET アプリケーションの高速化について探し始めてみた - その4 - ( ConcurrentDictionary )

 Dictionary をスレッドセーフにするには、自前で Monitor などを使用してそれぞれのメソッドをロックする必要がありました。.NET 4.0 より ConcurrentDictionary というクラスが追加されています。(今更?) 複数のスレッドから同時にアクセスできるキーと値のペアのスレッド セーフな Dictinary です。

※下記はMSDNから抜粋

class CD_GetOrAddOrUpdate
{
    // Demonstrates: 
    //      ConcurrentDictionary<TKey, TValue>.AddOrUpdate() 
    //      ConcurrentDictionary<TKey, TValue>.GetOrAdd() 
    //      ConcurrentDictionary<TKey, TValue>[] 
    static void Main()
    {
        // Construct a ConcurrentDictionary
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();

        // Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
        Parallel.For(0, 10000, i =>
        {
            // Initial call will set cd[1] = 1.   
            // Ensuing calls will set cd[1] = cd[1] + 1
            cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
        });

        Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]);

        // Should return 100, as key 2 is not yet in the dictionary 
        int value = cd.GetOrAdd(2, (key) => 100);
        Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value);

        // Should return 100, as key 2 is already set to that value 
        value = cd.GetOrAdd(2, 10000);
        Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value);
    }
}

Exist メソッドでいちいち存在チェックをする必要がないので、ソースの可読性も向上しそうです。ぱっと見高速化もできそうですが.... あ、けどなんか遅いって噂ですね。今度検証してみよう。