【C#】List vs HashSet vs Dictionary

Uncategorized
356 words

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

環境

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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);
}
}
}

実行結果

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

Linq はどれも同じ速さ

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);

実行結果

1
2
3
List: 857ms
HashSet: 857ms
Dictionary: 857ms

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

まとめ

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

Linq は遅い。