ストリームvsビューvsイテレータ


136

Scalaのストリーム、ビュー(SeqView)、イテレータの違いは何ですか?これは私の理解です:

  • それらはすべて遅延リストです。
  • ストリームは値をキャッシュします。
  • イテレータは一度しか使用できませんか?最初に戻って値を再度評価することはできませんか?
  • ビューの値はキャッシュされませんが、何度でも評価できますか?

それで、ヒープ領域を節約したい場合は、イテレータ(リストを再度トラバースしない場合)またはビューを使用する必要がありますか?ありがとう。


7
私は以前にこれに答えたことがありますが、それを見つける方法は?ため息...
ダニエルC.ソブラル

回答:


182

まず、それらはすべて非厳密です。これは、関数に関連する特定の数学的な意味を持っていますが、基本的に、事前ではなくオンデマンドで計算されることを意味します。

Stream確かに遅延リストです。実際、Scalaでは、Streama Listはのtailですlazy val。計算されると、値は計算されたままになり、再利用されます。または、あなたが言うように、値はキャッシュされます。

Iteratorそれがあるので、一度だけ使用することができトラバーサルポインタ 自体でコレクションコレクションに、そしてません。何Scalaで、それは特別なことは、あなたがこのような変換を適用することができるという事実であるmapfilterし、単に新しい取得Iteratorあなたは次の要素を求める場合にのみこれらの変換を適用するであろうが。

Scalaは以前はリセットできるイテレータを提供していましたが、一般的な方法でサポートするのは非常に難しく、バージョン2.8.0を作成していませんでした。

ビューは、データベースビューのように表示されることを意図しています。これは、コレクションに適用して「仮想」コレクションを生成する一連の変換です。あなたが言ったように、すべての変換は、そこから要素をフェッチする必要があるたびに再適用されます。

Iteratorとビューの両方に優れたメモリ特性があります。Stream素晴らしいですが、Scalaの主な利点は、無限シーケンス(特に、再帰的に定義されたシーケンス)を記述することです。一つはできるのすべてを保つ避けるStream必ずそのへの参照を保持しないことで、けれども、メモリにhead(例えば、使用してdefの代わりにval定義しますStream)。

ビューによって発生するペナルティのため、通常forceは変換を適用した後、またはビューの合計サイズと比較してフェッチされる要素が少ないと予想される場合はビューとして保持する必要があります。


10
Iteratorまた、無限をプローブするのにも非常に便利です。可能な場合は、通常、ストリームよりも優先します。ストリームの本当の利点は、以前にアクセスされた値がキャッシュされることです。これは、以前の値で定義されるフィボナッチシーケンスのようなものを実装しようとするときに重大な恩恵です。
Kevin Wright

5
フィボナッチは最後の2つ前の値しか必要とせず、ストリーム全体を維持することは無駄です。アッカーマン関数はおそらく標準的な例です。
ユルゲン・ストローベル

4
@JürgenStrobelAckermannは、ストリームのインデックス付きアクセスがO(n)であるため、パフォーマンスが低下します。しかし、私はフィボナッチに関して同意します。
ダニエルC.ソブラル2012

9
そうそう。このため、Streamはどのようなキャッシングアプローチにも適さない選択肢となっています。
ユルゲン・ストローベル

7
この答えは非常に明確です。ドキュメントの一部である必要があります...ああ、実際にはそうです!ダニエルに感謝docs.scala-lang.org/tutorials/FAQ/stream-view-iterator.html
Svend
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.