お久しぶりです。大阪プログラマーの澤野です。
最近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
参考コード
ちなみにILSpyで参考コードのILを見るとInt32のGetHashCodeは以下のようにcallで呼ばれているのに対し
EnumのGetHashCodeはcontrainedを行ってからcallvirtで呼んでいます。
これはInt32より遅くなる気がしますね!
IntTestのIL
EnumTestのIL
それでは処理負荷の計測結果です。
計測結果
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周りのネタを考えてきます。