2012-10-12 25 views
5

The easiest way to convert a Java Collection to a Scala equivalent is using JavaConversions, since Scala 2.8.これらの暗黙のdefは、含まれているJava Collectionのラッパーを返します。JavaコレクションからScala並列コレクションを作成する方法

Scala 2.9では、並列処理が導入されました。この処理では、コレクションに対する操作を並行して実行し、結果を後で収集できます。

myCollection.par 

しかしJavaConversionsを使用してJavaコレクションから変換コレクションに「パー」を使用してに問題があります。これは、簡単に並列一つに既存のコレクションを変換するのと同じくらい簡単で、実装されています。ある、このようなリスト、キューやストリームなど

その他のコレクション、:Parallel Collection Conversionsで説明したように、本質的に連続的なコレクションは、すべての値を評価し、新しい並列コレクションに追加することによって、新しい並列コレクションに「強制」されています本質的には、 の順に要素がアクセスされなければならないという意味で順次である。 。これらのコレクションは、要素を同様の並列コレクションにコピーすることによって、パラレルバリアント に変換されます。 の例では、機能リストは、パラレルベクトルである標準不変の 並列シーケンスに変換されます。

これは、元のJavaコレクションを遅延評価しようとすると問題が発生します。たとえば、Java Iterableだけが返され、後でScala Iterableに変換された場合、Iterableの内容が熱心にアクセスされることを保証するものではありません。 したがって、各要素を評価するコストを負担することなく、Javaコレクションから並列コレクションを作成する必要はありますか?これはパラレルコレクションを使って並行して実行し、提供される最初のn個の結果をうまく '取る'ことによって回避しようとするこのコストです。

Parallel Collection Conversionsによれば、一定の時間を費やす一連のコレクションタイプがありますが、JavaConversionsでこれらのタイプを作成できる保証はありません(例: 'Set'それは 'HashSet'ですか?)。

+1

後者としてJavaConversionsではなくJavaConvertersを使用することをお勧めします。そこでは、.asScala.toList.parのようなことができるはずです。 –

答えて

4

最初に、JavaコレクションからJavaConversionを介して取得されたすべてのコレクションは、デフォルトでは並列化可能なScalaコレクションではありません。つまり、常に対応する並列コレクション実装に再評価されます。この理由は、並列実行は少なくともSplittersの概念に依存しているため、異なるプロセッサーが処理できるより小さなサブセットに分割可能でなければなりません。

Javaのコレクションがデータ構造の意味でどのように見えるのかわかりませんが、それが木のようなものか、要素が遅れて評価される配列の場合は、Splitterを簡単に実装できる可能性があります。

force JavaコレクションAPIを実装するレイジーコレクションを気にかけたくない場合は、唯一のオプションはその特定の遅延型Javaコレクションのimplement a new type of a parallel collectionです。この新しい実装では、イテレータを分割する手段(つまり、Splitter)を提供する必要があります。

データ構造を分割する方法を知っているこの新しい並列コレクションを実装したら、特定のJavaコレクション用のカスタムScalaラッパーを作成する必要があります(この時点ではほんの少しの定型文ですJavaConversions)、特定の並列コレクションを返すためにそのparを上書きします。

索引付けされたシーケンスに対してもこれを一般的に行うことができます。 Javaコレクションが特に効率的なgetメソッドを持つシーケンス(Javaの場合はList)であることを考えると、をgetを初期範囲の0からsize - 1までコールし、この範囲を細分して分割するイテレータとして実装することができます。

この場合、標準ライブラリへのパッチはいつでも歓迎します。

1

パラレルではランダムアクセスが必要であり、java.lang.Iterableはそれを提供しません。これは、コンバージョンがあなたを楽に過ごすことはないという根本的な不一致です。

プログラミング以外のアナロジーを使用するには、シンガポールからイングランドに1人、オーストラリアからシンガポールに1人を同時に送って、オーストラリアからイギリスに人を連れて行くことはできません。

ライブのデータストリームを処理している場合、5分前のデータと同時にデータを処理することで、データを並列化することはできません。

Iterableの代わりにjava.util.List.listIterator(Int)のようなランダムアクセスを少なくとも提供するものが必要です。

+0

私は次の要素(すなわち、Iterable.iterator()。next())を取得するための各呼び出しがスレッド内で実行されたと思います。 –

関連する問題