HEXA BLOG
ヘキサブログ
プログラム
[c#]EnumのGetHashCodeは遅いの?
お久しぶりです。大阪プログラマーの澤野です。
最近EnumのGetHashCodeの実装を知る機会があり、もしかしてEnumのGetHashCodeは遅いの?と疑問に思ってしまったので
Int32.GetHashCodeとの処理負荷の比較をゆるーく行いました。
間違っているかもしれないので参考程度に見てくれればと思います。
早速ですがInt32とEnumのGetHashCodeの実装は以下の通りです。
Int32.GetHashCodeの実装
値をそのまま返すだけです。
ReferenceSource
Enum.GetHashCodeの実装
型でswitchしてからキャストして返しています。
ReferenceSource
非常に簡易にですが以下のコードで処理負荷の比較を行ってみようかと思います。
環境
ターゲットフレームワーク:.Net Core2.1
プロセッサ:Intel(R) Core(TM) i7-6700 CPU @3.40GHz
参考コード
enum TestEnum : int { | |
Test0 = 1, | |
} | |
static void Main(string[] args) | |
{ | |
// 500万回GetHashCodeを呼ぶ | |
const int MaxCount = 5000000; | |
// EnumTest | |
{ | |
var sum = 0; | |
var sw = new System.Diagnostics.Stopwatch(); | |
for (var index = 0; index < MaxCount; ++index) | |
{ | |
sw.Start(); | |
sum += TestEnum.Test0.GetHashCode(); | |
sw.Stop(); | |
} | |
System.Diagnostics.Trace.WriteLine($"EnumTest = {sw.ElapsedMilliseconds}ミリ秒, Sum = {sum}"); | |
} | |
// IntTest | |
{ | |
var sum = 0; | |
int value0 = 1; | |
var sw = new System.Diagnostics.Stopwatch(); | |
for (var index = 0; index < MaxCount; ++index) | |
{ | |
sw.Start(); | |
sum += value0.GetHashCode(); | |
sw.Stop(); | |
} | |
System.Diagnostics.Trace.WriteLine($"IntTest = {sw.ElapsedMilliseconds}ミリ秒, Sum = {sum}"); | |
} | |
} |
ちなみにILSpyで参考コードのILを見るとInt32のGetHashCodeは以下のようにcallで呼ばれているのに対し
EnumのGetHashCodeはcontrainedを行ってからcallvirtで呼んでいます。
これはInt32より遅くなる気がしますね!
IntTestのIL
// num2 += num3.GetHashCode(); | |
IL_006f: ldloc.s 4 | |
IL_0071: ldloca.s 5 | |
IL_0073: call instance int32 [System.Runtime]System.Int32::GetHashCode() |
EnumTestのIL
// num += TestEnum.Test0.GetHashCode(); | |
IL_0012: ldloc.0 | |
IL_0013: ldc.i4.1 | |
IL_0014: stloc.3 | |
// (no C# code) | |
IL_0015: ldloca.s 3 | |
IL_0017: constrained. ConsoleApp1.Program/TestEnum | |
IL_001d: callvirt instance int32 [System.Runtime]System.Object::GetHashCode() |
それでは処理負荷の計測結果です。
計測結果
Debugビルド
EnumTest = 438ミリ秒, Sum = 5000000
IntTest = 371ミリ秒, Sum = 5000000
Releaseビルド
EnumTest = 363ミリ秒, Sum = 5000000
IntTest = 330ミリ秒, Sum = 5000000
処理負荷の計測方法が間違っている気がしなくもないですが上記のコードで計測する限り
GetHashCodeを500万回呼ぶとEnum.GetHashCodeの方がReleaseビルドで30msほど遅くなっていることが分かります。
しかし、500万回も呼ぶことはそうそうないので処理負荷はほとんど誤差といっても良いのではないでしょうか。
何とも面白くない結果になってしまいましたがEnumのGetHashCodeは使用を懸念するほど遅くはなさそうです。
次回はc#のOpCode周りのネタを考えてきます。
CATEGORY
- about ヘキサ (166)
- 部活動 (6)
- CG (18)
- プロジェクトマネジメント (1)
- 研修 (5)
- 美学 (1)
- いいモノづくり道 (232)
- 採用 -お役立ち情報も- (149)
- プログラム (188)
- デザイン (99)
- ゲーム (274)
- 日記 (1,104)
- 書籍紹介 (113)
- その他 (875)
- 就活アドバイス (20)
- ラーメン (3)
- ライフハック (25)
- イベント紹介 (10)
- 料理 (23)
- TIPS (7)
- 怖い話 (3)
- サウンド (5)
- 子育て (1)
- 筋トレ (1)
- 商品紹介 (21)
- アプリ紹介 (31)
- ソフトウェア紹介 (33)
- ガジェット紹介 (12)
- サイト紹介 (10)
- 研究・開発 (34)
- 回路図 (4)
- アナログゲーム (40)
- 交流会 (21)
- 報告会 (3)
- インフラ (25)
- グリとブラン (6)
- カメラ (9)
- クラフト (27)
- 部活 (14)
- 画伯 (15)
- カレー (6)
- 音楽(洋楽) (6)
- 映画・舞台鑑賞 (43)
- 飼育 (5)
- いぬ (8)
- ねこ (19)
ARCHIVE
- 2025年
- 2024年
- 2023年
- 2022年
- 2021年
- 2020年
- 2019年
- 2018年
- 2017年
- 2016年
- 2015年
- 2014年
- 2013年
- 2012年
- 2011年
- 2010年
- 2009年
- 2008年
- 2007年