5

Java コレクションを同等の Scala に変換する最も簡単な方法は、Scala 2.8 以降、JavaConversions を使用することです。. これらの暗黙的な定義は、含まれている Java コレクションのラッパーを返します。

Scala 2.9 では、コレクションに対する操作を並行して実行し、後で結果を収集できる並列コレクションが導入されました。これは簡単に実装できます。既存のコレクションを並列コレクションに変換するのは次のように簡単です。

myCollection.par

しかし、JavaConversions を使用して Java コレクションから変換されたコレクションで「par」を使用すると問題が発生します。Parallel Collection Conversionsで説明されているように、本質的にシーケンシャルなコレクションは、すべての値を評価して新しい並列コレクションに追加することにより、新しい並列コレクションに「強制」されます。

リスト、キュー、ストリームなどのその他のコレクションは、要素に次々にアクセスする必要があるという意味で、本質的にシーケンシャルです。これらのコレクションは、要素を同様の並列コレクションにコピーすることによって、並列バリアントに変換されます。たとえば、機能リストは、並列ベクトルである標準の不変並列シーケンスに変換されます。

これは、元の Java コレクションが遅延評価されることを意図している場合に問題を引き起こします。たとえば、Java Iterable のみが返され、後で Scala Iterable に変換された場合、Iterable のコンテンツが積極的にアクセスされることを意図しているかどうかの保証はありません。では、各要素を評価するコストを負担することなく、Java コレクションから並列コレクションを作成するにはどうすればよいでしょうか? 並列コレクションを使用してそれらを並列に実行し、提供される最初の n 個の結果を「取得」することで回避しようとしているのは、このコストです。

Parallel Collection Conversionsによると、一定の時間がかかる一連のコレクション型がありますが、これらの型を JavaConversions で作成できることを保証する方法はないようです (たとえば、'Set' は作成できますが、それは「HashSet」ですか?)。

4

2 に答える 2

4

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

あなたの Java コレクションがデータ構造の意味でどのように見えるかはわかりませんが、それがツリーのようなものであるか、その下にある要素が遅延評価される配列である場合、簡単にSplitter.

forceJava コレクション API を実装する遅延コレクションを積極的に作成したくない場合、唯一の選択肢は、その特定の遅延 Java コレクション用に新しいタイプの並列コレクションを実装することです。この新しい実装では、反復子 (つまり a Splitter) を分割する手段を提供する必要があります。

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

インデックス付きシーケンスに対して一般的にこれを行うことさえできるかもしれません。Java コレクションがList特に効率的なメソッドを持つシーケンス (Java では a ) であるとすると、 を からまでの初期範囲内で呼び出す反復子としてget実装でき、この範囲を細分化することによって分割されます。Splitterget0size - 1

もしそうなら、標準ライブラリへのパッチはいつでも歓迎します。

于 2012-10-12T13:07:29.793 に答える
1

Parallel はランダム アクセスを必要とし、java.lang.Iterable はそれを提供しません。これは基本的なミスマッチであり、コンバージョンの量が快適に通過することはありません.

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

または、プログラミングでデータのライブ ストリームを処理している場合、レイテンシを追加せずに 5 分前のデータと同時に今からのデータを処理して並列化することはできません。

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

于 2012-10-12T13:07:18.810 に答える