Cats EffectとVirtual Threads

ScalaMatsuri 2023のdiscordの会話を雑に勝手に転載しておくだけのblog。


We've looked into it! The way this would work, more than likely, is the implementation of Fiber for IO would check to see if VirtualThread is available, and if so, an alternative implementation would be instantiated any time you call .start. However, there are some serious limitations which arise. For starters, Cats Effect has a custom thread pool which is very heavily optimized, supports blocking regions (which are still required, even with Loom), and which supports additional functionality like timers and (in future!) native I/O event loops.

私たちはそれを調べました!おそらく、これが機能する方法は、 IO の Fiber の実装が VirtualThread が使用可能かどうかを確認し、使用可能であれば、 .startを呼び出すたびに代替実装がインスタンス化されることです。ただし、発生するいくつかの重大な制限があります。まず第一に、Cats Effect にはカスタム スレッド プールがあり、これは非常に最適化されており、 blocking リージョン (Loom でもまだ必要です) をサポートし、タイマーや (将来的には!) ネイティブ I/O イベントなどの追加機能をサポートします。ループします。

Unfortunately, Loom forces you to use the ForkJoinThreadPool from the JDK, meaning that we cannot use Cats Effect's more advanced runtime features.

残念ながら、Loom は JDK の ForkJoinThreadPool を使用することを 強制 します。つまり、Cats Effect のより高度なランタイム機能を使用することはできません。

Additionally, Loom doesn't allow us to avoid the primary source of microbenchmark performance pressure with systems like Cats Effect: namely, the allocation cost of the actual IO objects (e.g. whenever you call flatMap, you're allocating two objects). This penalty is unavoidable because it's part of the API, so Loom offers no benefits there.

さらに、Loom では、Cats Effect のようなシステムによるマイクロベンチマーク パフォーマンス プレッシャーの主な原因、つまり実際の IO オブジェクト (e.gの割り当てコストを回避することはできません。 flatMapを呼び出すたびに、2 つのオブジェクトが割り当てられます)。これは API の一部であるため、このペナルティは避けられないため、Loom には何のメリットもありません。

Ultimately, Loom only replaces the IO.async implementation (in part! we still need some of that machinery to support cancelation, which Loom doesn't help with), as well as parts of the continuation stack. However, the continuation stack is exceptionally efficient, so it's possible that VirtualThread is actually making things slower (more experimentation is required).

最終的に、Loom は IO.async の実装 (部分的には! Loom が役に立たないキャンセルをサポートするためにまだその機構の一部が必要です) と、継続スタックの一部を置き換えるだけです。ただし、継続スタックは非常に効率的であるため、 VirtualThread が実際に処理を 遅く している可能性があります (さらに実験が必要です)。

If Loom exposed its internal Continuation mechanism, we would probably be able to take advantage of it to offer a slightly improved IO on those JVM versions (specifically, we would take advantage of it for IO.async), but it wouldn't be a profoundly impactful change.

Loom が内部の Continuation メカニズムを公開した場合、おそらくそれを利用して、これらの JVM バージョンでわずかに改善された IO を提供できます (具体的には、 IO.asyncでそれを利用します)。重大な影響を与える変更にはなりません。