BlackJumboDog .NET Core 性能向上 メモ 2

これの続ぎ

リクエストを処理する中で、遅くなっているものは何か?
よく考えられるもは、ロジックの無駄な処理(処理する必要のないものを処理している)。リソースの使い方。
で、まずはロジックの無駄という意味では、意味のない処理は見つからず。
で、遅くなっているところというのを考えると
リソースの確保の部分。
new byte [ XX ];
これは、ある程度のサイズになったとき、Heapの確保が発生するので、場合によって、数msかかる。これが1か所ならまぁいいのですが、中の処理では、Socketの読み込みバッファから、エンコード用のバッファ、出力用のバッファまで広く使っており、1回のリクエストで、少なくとも5回以上は生成しておりました。

これを何とかできないか?と考えたのが、BufferPoolというクラスを作ることでした。

https://github.com/darkcrash/bjd5/blob/3212cf26eca2f1c90ee545df4b3307fc654abf73/Bjd.Common/Memory/BufferPool.cs

これの役目は・・・

  • byte配列の確保を毎回やらせないことで、GCのコストを抑える。Heapの確保と解放をあまり発生させない。
  • 一定数事前に配列を生成し、領域を確保することで生成のコストを抑える。
  • 必要なサイズに応じたものを返す。
  • 足りなければ、作る。
  • 足りなくて作ったものが、既定の確保しておく領域を上回る場合には、解放する。

これで得られる恩恵は、思ってた以上に大きく、リクエストあたり数ms減りました。

これに対して個人的な見解は・・・・
GCはリソースやメモリの再利用があるので、そこである程度同じことさせているときは、次第に早くなるのですが、HTTPリクエストやら、Socket通信などでは、同じリソースのサイズを要求しないことが多く、メモリの断片化が起きたり。GCが動くことで、CPUリソースを消費したりということではないかなぁと思ったりしたが、それを明確に確認できる方法は思いつかなかった。。。GCの呼び出し回数が減っているというくらいかな。

 

続く・・・