【C#】List vs HashSet vs Dictionary

アプリ開発

繰り返し処理とLinqのパフォーマンステストです。

環境

  • Windows 10 Home 21H1
  • Visual Studio 2019
  • .NET Core 3.1

繰り返し処理は List型 が一番早い

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // テストデータ作成
            var list = new List<int>();
            var hash = new HashSet<int>();
            var dict = new Dictionary<int, int>();
            for (var i = 0; i < 10000000; i++)
            {
                list.Add(i);
                hash.Add(i);
                dict.Add(i, i);
            }

            var sw = new Stopwatch();
            decimal total = 0;

            Console.WriteLine("繰り返し処理で値の合計を算出する。");

            sw.Start();
            foreach (var item in list)
            {
                total += item;
            }
            sw.Stop();
            Console.WriteLine("List: {0}ms", sw.ElapsedMilliseconds);

            total = 0;

            sw.Start();
            foreach (var item in hash)
            {
                total += item;
            }
            sw.Stop();
            Console.WriteLine("HashSet: {0}ms", sw.ElapsedMilliseconds);

            total = 0;

            sw.Start();
            foreach (var item in dict)
            {
                total += item.Value;
            }
            sw.Stop();
            Console.WriteLine("Dictionary: {0}ms", sw.ElapsedMilliseconds);

            total = 0;

            sw.Start();
            foreach (var item in dict.Keys)
            {
                total += item;
            }
            sw.Stop();
            Console.WriteLine("Dictionary.Keys: {0}ms", sw.ElapsedMilliseconds);

            total = 0;

            sw.Start();
            foreach (var item in dict.Values)
            {
                total += item;
            }
            sw.Stop();
            Console.WriteLine("Dictionary.Values: {0}ms", sw.ElapsedMilliseconds);
        }
    }
}

実行結果

繰り返し処理で値の合計を算出する。
List: 122ms
HashSet: 254ms
Dictionary: 428ms
Dictionary.Keys: 560ms
Dictionary.Values: 687ms

Linq はどれも同じ速さ

先ほどのソースを改造して Linq を使って取得した場合、どうなるか確認してみました。

sw.Start();
var listFirst = list.FirstOrDefault(x => x == 1000);
sw.Stop();
Console.WriteLine("List: {0}ms", sw.ElapsedMilliseconds);

sw.Start();
var hashFirst = hash.FirstOrDefault(x => x == 1000);
sw.Stop();
Console.WriteLine("HashSet: {0}ms", sw.ElapsedMilliseconds);

sw.Start();
var dictFirst = dict.FirstOrDefault(x => x.Key == 1000);
sw.Stop();
Console.WriteLine("Dictionary: {0}ms", sw.ElapsedMilliseconds);

実行結果

List: 857ms
HashSet: 857ms
Dictionary: 857ms

速さに違いはなかったですが、遅いです。

まとめ

意外だったのが HashSet型 より List型 の方が早かったこと。

Linq は遅い。

タイトルとURLをコピーしました