.NET アプリケーションの高速化について探し始めてみた - その5 - ( ConcurrentDictionary のパフォーマンス計測 )
.NET アプリケーションの高速化について探し始めてみた - その4 - で取り上げた ConcurrentDictionary のパフォーマンスを計測してみたいと思います。検証しようかと思ったら、仮想環境を格納してある外付けハードディスクを忘れてしまいました...こんな時は、やっぱり Windows Azure です。下図通り、Visual Studio 2013 Preview が使用できるので、Azure 環境を使用して検証してみたいと思います。
仮想マシンのサイズは『M』で、CPU:2コア、2.10GHz, メモリ:3.5G の環境を作成しました。コーヒーを飲みながら、検証ロジックを考えている間にプロビジョニングが終了しました。プロビジョニングが速いですね。
Visual Studio 2013 Preview を今回はじめて使ったので、とりあえず画面ショット。
検証に使用するソースコードは下記の通りです。同一の条件とするため、要素の追加は、instance[key] = value、 取得は、TryGetValue(key, out value) メソッドを使用しています。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string args)
{
const int MAXITEMS = 100000;
var accessIndex = new List<string>(MAXITEMS);
var list = new List<KeyValuePair<string, object>>();
for (int i = 0; i < MAXITEMS; i++)
{
list.Add(new KeyValuePair<string, object>(i.ToString(), i));
accessIndex.Add(i.ToString());
}
var r = new Random(Environment.TickCount);
var randomIndexesList = new List<string>(MAXITEMS);
while (accessIndex.Count > 0)
{
int index = r.Next(accessIndex.Count);
string value = accessIndex[index];
accessIndex.RemoveAt(index);
randomIndexesList.Add(value);
}
string randomIndexes = randomIndexesList.ToArray();
//ConcurrentDictionaryへの要素追加に関する計測
var lisw = Stopwatch.StartNew();
var cdictionary = new ConcurrentDictionary<string, object>();
for (int i = 0; i < MAXITEMS; i++)
{
cdictionary[i.ToString()] = i;
}
lisw.Stop();
Console.WriteLine("ConcurrentDictionary(Add) - {0,10} ms", lisw.ElapsedMilliseconds);
//Dictionaryへの要素追加に関する計測
var ldsw = Stopwatch.StartNew();
var dictionary = new Dictionary<string, object>();
for (int i = 0; i < MAXITEMS; i++)
{
dictionary[i.ToString()] = i;
}
ldsw.Stop();
Console.WriteLine("Dictionary(Add) - {0,10} ms", ldsw.ElapsedMilliseconds);
//ConcurrentDictionaryへの要素取得に関する計測
var igsw = Stopwatch.StartNew();
for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)
{
string i = randomIndexes[index];
object value;
cdictionary.TryGetValue(i, out value);
}
igsw.Stop();
Console.WriteLine("ConcurrentDictionary(TryGetValue) - {0,10} ms", igsw.ElapsedMilliseconds);
//Dictionaryへの要素取得に関する計測
var dgsw = Stopwatch.StartNew();
for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)
{
string i = randomIndexes[index];
object value;
dictionary.TryGetValue(i, out value);
}
dgsw.Stop();
Console.WriteLine("Dictionary(TryGetValue) - {0,10} ms", dgsw.ElapsedMilliseconds);
Console.Read();
}
}
}
※結果は、下図の通りです。
要素 = 100,000の場合
要素 = 10,000の場合
要素 = 1,000の場合
要素 = 100の場合
Dictionary のほうが若干高速(要素数が多い場合、追加に関しては ConcurrentDictionary が高速)なようですが、スレッドセーフであること、AddOrUpdate, GetOrAdd などの便利メソッドの存在を考えると、ConcurrentDictionary を使用したいですね。.NETFramework 4.5 でも様々な機能追加がされていますね。全然ついて行けてないです.......