.NET Core(C#): List・HashSetのContains性能比較

対象データが処理対象かの判定、データのユニーク化等の用途で、コレクション内のデータ存在チェックを行いたい場合があります。これを実現するために、List/Dictionary等のコレクションクラスのContains()メソッドを使用することになります。
ここでは、各コレクションクラスにおけるContainsの性能測定を行いました。

要約

  • 測定条件は次の通りです。
    • コレクションから文字列キーを検索する際の処理時間を計測する。
    • 対象のコレクションは、List, HaseSet, Dictionary(キーのみ)とする。
    • ランダムな文字列キーをN個格納したコレクションから、ランダムな文字列キーをN回検索する。
      (合計の照合回数は N × N = N2回)
    • 動作確認のため少なくても1件は合致させる。
    • 使用する文字列キーはそれぞれ、半角数字・英大小文字を含む4桁文字とする。
  • 実行環境は次の通りです。
    ハードウェアCPU: AMD Ryzen 5 3400G, MEM: 16GB, SSD: 130GB
    OSWindows 10(64ビット)
    IDEMicrosoft Visual Studio Community 2019(16.8.5) + C#(8.0)
  • 測定結果は次の通りです。
    ※N個のキーが登録されたコレクションからキーをN回検索する場合の照合回数を「N2」と表記しています。
    ※計測時間の単位はミリ秒であり、[ms]と表記しています。
    ※計測時間が1 [ms]未満の場合は0 [ms]と表記しています。

    種類照合回数
    10021,000210,0002100,0002
    List0 [ms]9 [ms]720 [ms]73,102 [ms]
    HashSet0 [ms]0 [ms]0 [ms]7 [ms]
    Dictionary0 [ms]0 [ms]0 [ms]7 [ms]
  • 考察

詳細

サンプルコード

実行結果

  • Contains性能比較(bucketSize: 100)
    List(100×100) -> elapsed=0[ms], hit=1
    HashSet(100×100) -> elapsed=0[ms], hit=1
    Dictionary(100×100) -> elapsed=0[ms], hit=1
  • Contains性能比較(bucketSize: 1000)
    List(1000×1000) -> elapsed=9[ms], hit=1
    HashSet(1000×1000) -> elapsed=0[ms], hit=1
    Dictionary(1000×1000) -> elapsed=0[ms], hit=1
  • Contains性能比較(bucketSize: 10000)
    List(10000×10000) -> elapsed=720[ms], hit=9
    HashSet(10000×10000) -> elapsed=0[ms], hit=9
    Dictionary(10000×10000) -> elapsed=0[ms], hit=9
  • Contains性能比較(bucketSize: 100000)
    List(100000×100000) -> elapsed=73,102[ms], hit=657
    HashSet(100000×100000) -> elapsed=7[ms], hit=657
    Dictionary(100000×100000) -> elapsed=7[ms], hit=657