2016-12-21 3 views
4

RDDにmapPartitionsを適用すると、パーティションは反復可能なオブジェクトを取得することに気付きました。 mapPartitions関数内で、次に、反復可能オブジェクトのtoArrayメンバー関数を呼び出して、その反復可能オブジェクトをArrayオブジェクトに変換します。 toArrayの呼び出しにはコピーが必要ですか、それとも単にメモリと同じ部分を配列として参照するだけですか?コピーが必要な場合は、コピーを防止する方法は何ですか?スパークにおけるイテラブルと配列の関係

答えて

3

質問に対する重要な修正 - mapPartitionsの間に公開されたパーティションデータ構造はIteratorであり、Iterableではありません。

  • Iteratorは、一度、コレクションの各要素を訪問することができnext()hasNext()方法を、持っている:ここでは、インタフェースの違いです。イテレータのメソッドが呼び出されると、最後の要素はなくなります(変数に変数を格納していない限り)。
  • Iterableには、いつでも必要なときにIteratorを生成する機能があります。これにより、必要な回数だけ各要素を訪問することができます。

実装に関しては、Iteratorがデータをストリームスルーできます。実際には、一度に1つの要素しかメモリに格納する必要はありません。next()が呼び出されるとロードされます。あなたがSpark(sc.textFile)でテキストファイルを読み込んでいるのであれば、これはまさにこれを行い、メモリをほとんど使いませんので、パーティションを使って単純な繰り返しを行うことができます。

iterator.toArrayに電話することは絶対に許可されていますが、そうしたくないかもしれません。すべてのデータをメモリに格納することになります(一度に1つの要素しかロードできません)。そして、各データをコピーします(プリミティブの場合は、Int )、またはデータごとに新しい参照を割り当てます(AnyRefの場合、Array[_]など)。このコピーを防ぐ方法はありません。

パーティションイテレータを配列に変換することがあなたのやりたいことですが、これらのユースケースはまれです。メモリが不足し、不要な割り当てやGCのためにアプリケーションの処理速度が低下する危険性があるため、実際に必要かどうかを考えてみてください!

+0

次に、私の次の質問は、一度に1つの要素ではなく、特定の数の要素を得ることができますか? – pythonic

+1

これを行うための準備はできていませんが、 'Iterator'を拡張し、最後の' n'要素を追跡することができます。インスピレーションを探しているなら、 'iterator.buffered'を見てください。これは、次の要素を削除せずに見ることができる' BufferedIterator'を構築します。 – Tim

+1

おそらく 'iterator.grouped(size)'が必要です。これは、指定されたサイズの 'Seq'よりもイテレータを与えるでしょう。 –

関連する問題