ノートの端の書き残し

UnityやらC#やら。設計が得意かもしれない。

ArrayPoolUtil

ArrayPool

System.Buffers.dllに含まれるクラスで、名前の通り配列のオブジェクトプールです。
C#は配列を普通に作るとGC管理下であるマネージドヒープに必ず確保しなければならないというありがた迷惑な仕様をしていますが、この厄介な性質をほぼ完全に解消してくれるスゴイやつです。オブジェクトプールなので返却だけ忘れないようにしなければなりませんが、一時的な配列は(stackallocとか使えるならそれでいいけど)もうこいつでいいんじゃないでしょうか。

ArrayPoolUtil

先日、UniTaskの中のコードを見ているとArrayPoolUtilというクラスを見つけました。

github.com

UniTask.WhenAllなどは引数にIEnumerable<UniTask>を取れるのですが、IEnumerableをそのまま使っては毎フレーム参照されてEnumeratorの生成が無駄なので、このArrayPoolUtilのメソッドを使って、可能な限りアロケーションを無くして配列を作っているようです。 ちなみにここで使われているArrayPoolはUniTask内製のArrayPoolです。本家.NETのArrayPoolがUnityでデフォルトで使えるようになったのはUnity2021からで、UniTaskライブラリの汎用性を考えて、依存パッケージを増やすのを嫌ったのかなと思います。

Materialize

大事なのはMaterializeで、これは拡張メソッドとして使えば、要するにLinqのToArrayのArrayPool利用バージョン、みたいなものです。 UniTaskではこれはinteranalで宣言されていてそのまま使えませんが、内容はUniTaskとは無関係なものなので、パクって汎用的に使えると思います。
もちろんその際にはArrayPoolはSystem.Buffersのものを使えばいいでしょう。