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

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

Immutable な Collection のパフォーマンス計測をしてみる

 早速、ImmutableDictionary に関するパフォーマンス検証を、Dictionary と比較しながら実施してみました。計測に用いたプログラムは下記の通りです。ロードおよび取得のパフォーマンスを計測してみました。(どこかのページで取得したコードなのですが、どこか忘れてしまいました。今回の検証に合わせて、少し改変をしています。)

※Dictionary に、100, 1000, 10000, 100000 と要素をロードし、その要素数分取得を繰り返した時のパフォーマンス計測を実施しました。

 

using System;

using System.Collections.Generic;

using System.Collections.Immutable;

using System.Diagnostics;

 

namespace PerformanceTest

{

    class Program

    {

        static void Main(string args)

        {

            {

                foreach (int MAXITEMS in new int { 100, 1000, 10000, 100000 })

                {

                    Console.WriteLine("\n# - {0}", MAXITEMS);

 

                    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();

 

 

                    var lisw = Stopwatch.StartNew();

                    var idictionary = ImmutableDictionary.Create<string, object>(list);

                    lisw.Stop();

                    Console.WriteLine("Immutable Dictionary(Load)  - {0,10} ms", lisw.ElapsedMilliseconds);

 

 

                    var ldsw = Stopwatch.StartNew();

                    var dictionary = new Dictionary<string, object>();

                    for (int i = 0; i < MAXITEMS; i++)

                    {

                        dictionary.Add(i.ToString(), i);

                    }

                    ldsw.Stop();

                    Console.WriteLine("Dictionary(Load)            - {0,10} ms", ldsw.ElapsedMilliseconds);

 

                    var igsw = Stopwatch.StartNew();

                    for (int index = 0, indexMax = randomIndexes.Length; index < indexMax; index++)

                    {

                        string i = randomIndexes[index];

                        object value;

                        idictionary.TryGetValue(i, out value);

                    }

                    igsw.Stop();

                    Console.WriteLine("Immutable Dictionary        - {0,10} ms", igsw.ElapsedMilliseconds); 

 

                    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                  - {0,10} ms", dgsw.ElapsedMilliseconds);

 

                }

                Console.Read();

            }

 

        }

    }

}

 

結果は、

f:id:koogucc11:20130609230823j:plainロード、取得ともに Dictionary のほうが高速なんですね。ImmutableDictionary のほうが高速かと思っていました。そうなんですぇ...イメージ的に Immutable のほうが速いかと思っていました.....