1. ホーム
  2. haskell

[解決済み] Lazy I/Oの何がそんなに悪いのか?

2023-04-06 23:34:26

質問

一般的に、プロダクションコードでは Lazy I/O を使用しない方が良いと聞いています。私の質問は、なぜかということです。おもちゃのようなものでなく、レイジー I/O を使用してもよいのでしょうか? そして、何が代替品 (たとえば列挙者) をより良くするのでしょうか?

どのように解決するのですか?

Lazy IO には、取得したリソースの解放が、プログラムがどのようにデータを消費するか(需要パターン)に依存するため、予測がつかないという問題があります。プログラムがリソースへの最後の参照を削除すると、GC は最終的に実行され、そのリソースを解放します。

レイジーストリームは 非常に でプログラムするのに便利なスタイルです。これがシェルパイプが楽しくて人気がある理由です。

しかし、リソースに制約がある場合 (高性能なシナリオや、マシンの限界までスケールすることを期待する生産環境のように)、GC にクリーンアップを依存することは不十分な保証になりえます。

スケーラビリティを向上させるために、時にはリソースを熱心に解放する必要があります。

では、遅延IOの代わりに、インクリメンタルな処理をあきらめない(その結果、多くのリソースを消費してしまう)方法は何でしょうか?私たちは foldl ベースの処理、別名 iteratees または enumerators があります。 Oleg Kiselyovによって2000年代後半に紹介されました。 と呼ばれ、それ以来、多くのネットワークベースのプロジェクトによって普及しました。

遅延ストリームとして、または1つの巨大なバッチとしてデータを処理する代わりに、最後のチャンクが読み込まれた時点でリソースの最終化が保証された、チャンクベースの厳密な処理を抽象化します。これはイテレートベースのプログラミングの本質であり、非常に優れたリソース制約を提供するものです。

イテレートベースのIOの欠点は、やや厄介なプログラミングモデルを持っていることです(素敵なスレッドベースの制御に対して、イベントベースのプログラミングにほぼ類似しています)。これは、どのプログラミング言語においても、間違いなく高度なテクニックです。そして、プログラミングの問題の大部分では、遅延IOは完全に満足のいくものです。しかし、多くのファイルを開いたり、多くのソケットで話したり、その他多くのリソースを同時に使用する場合は、イテレート (または列挙) アプローチが理にかなっている場合があります。