xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

FastEnum の初期化コストと利用指針

先日、FastEnum に関して非常に良い質問を受けました。短期間だけ起動してすぐにアプリ/インスタンスが死んでいくバッチ処理などにおいては、逆に初期化コストが大きくなってしまうのでないか?というものです。

確かに実行速度はメチャクチャ速いのですが、初期化コストがどの程度かは把握していませんでした。というのも、FastEnum は Web サービスやクライアントアプリなどの比較的長く利用されるものに対する応答速度を極限まで向上させることを目指しているので、初期化コストは warm up などで無視するものとして割り切っていました。ですが、確かに初期化コストを無視できないようなシチュエーションでの利用にどの程度耐えられるのかは気になります。

計測結果

ということで計測してみました。結果は以下のような感じです。呼び出し回数は、FastEnum の初期化の間に System.Enum の各種メソッドを何度呼び出せるのかを示しています。

処理 時間 [ns] 呼び出し回数 アロケーション [B]
FastEnum.Init 22,075.16 1.00 8,067
Enum.GetValues 1,337.97 16.50 352
Enum.GetNames 45.57 484.42 128
Enum.GetName 58.82 375.30 24
Enum.IsDefined 119.85 184.19 24
Enum.TryParse 139.91 157.78 24
Enum.ToString 33.95 650.23 24

f:id:xin9le:20191030000118p:plain

どうやら、一度ひとつの列挙型を初期化するのは 17 回ほど Enum.GetValues() を呼び出すのと同等なようです。Enum.ToString() であれば 650 回ほど。こう見ると結構遅い...気がする!初期化するときの実装には言うほど気を配っていないのが明るみに出た感じががが...。

と言っても、これらの数字は Web サービスのリクエスト数などからすればすぐにペイできます。初期化コストを気にするよりも一度のリクエストを高速に捌く方がずっと大切なので、言うほどではないでしょう。逆に短命なアプリやバッチ処理の場合は利用しない方が良いでしょう。ケースバイケースで使い分けるのが良いかと思います。

けど、やっぱりもうちょっと初期化コストを抑えるように頑張っても良いかもしれない...