C#
.NET
Unity

【Unity】.NET 4.6以降にて列挙型をキーとしたDictionaryは普通に速い

概要

列挙型(Enum)をキーとした辞書の実行速度に関して、これまでは遅いのでやめておくのが通説でしたが、
.NET4.6以降はかなり早くなっているとのことなので実際に調査してみました。

検証環境

  • Unity 2018.2.0f2
  • 1000万回ループした際にかかった時間を比較

テストコード

テストコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnumDictTest : MonoBehaviour {
  private const int RepeatNum = 10000000;
  private enum TestEnum {
    ID1,
    ID2,
    ID3,
    ID4,
    ID5,
  }

  void Start() {
    var EnumDic = new Dictionary<TestEnum, string>(){
    {TestEnum.ID1 , "ID1"},
    {TestEnum.ID2 , "ID2"},
    {TestEnum.ID3 , "ID3"},
    {TestEnum.ID4 , "ID4"},
    {TestEnum.ID5 , "ID5"},
  };
    var IntDic = new Dictionary<int, string>(){
    {1, "1"},
    {2, "2"},
    {3, "3"},
    {4, "4"},
    {5, "5"},
  };

    // 検証開始
    var sw = new System.Diagnostics.Stopwatch();
    string tmp;
    sw.Start();
    for (int i = 0; i < RepeatNum; i++) {
      tmp = EnumDic[TestEnum.ID1];
      tmp = EnumDic[TestEnum.ID2];
      tmp = EnumDic[TestEnum.ID3];
      tmp = EnumDic[TestEnum.ID4];
      tmp = EnumDic[TestEnum.ID5];
    }
    sw.Stop();
    System.TimeSpan ts = sw.Elapsed;
    Debug.Log("Enum time: " + ts);
    sw.Reset();

    sw.Start();
    for (int i = 0; i < RepeatNum; i++) {
      tmp = IntDic[1];
      tmp = IntDic[2];
      tmp = IntDic[3];
      tmp = IntDic[4];
      tmp = IntDic[5];
    }
    sw.Stop();
    ts = sw.Elapsed;
    Debug.Log("Int time : " + ts);
  }
}

検証結果

検証結果
.NET4.6以前
Enum time: 00:00:13.4472780
Int time : 00:00:02.1872700

.NET4.6に変更
Enum time: 00:00:02.6733198
Int time : 00:00:02.3185855

13.4秒 → 2.7秒 に短縮されてました。

まとめ

たしかに.NET4.6以降だと以前とは比べ物にならないほど高速化されていますね。
流石にIntよりは少し遅いですが、それでも十分に許容範囲だと思います。
どうしても速度が欲しい場合はIntで、それ以外は可読性重視で列挙型をキーにしても良さそうです。