2012-01-20 4 views
0

Scaladocによると、Scalaの並行ビューで奇妙な行動

ビューには、いくつかのコレクションの怠惰なバージョンです。 mapやfilter、++などのコレクショントランスフォーマは、ビューに適用されたときに要素をトラバースしません。代わりに、操作を適用する必要があるという事実を単に記録する新しいビューを作成します。

つまり、要素にアクセスするまで操作は適用されません。しかし、パラレルについてはどうですか?

は、この例を見てみましょう:

def tn = Thread.currentThread.getName 
val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") 
val pvs = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase} 

第二には、次のように出力します:

enter image description here

あなたはpvsforeachを適用すると、それは出力: enter image description here

私はなぜperforma のNCEパラレルスタイルは、通常のものと同じではありません。

val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") // or read from a text file , e.g. article.txt 
strList.view.filter{s => println("f"); s == "I"}.map{s => println("m"); s.toLowerCase}.foreach(s => println("p")) 
+4

可能であれば、イメージではなくカットごとにテキストを提供してください。 Btw: 'tn'とは何ですか、スレッド名ですか? –

+0

画像がコピー&ペーストされたテキストの方がずっと良いでしょう。 –

答えて

1

それは本質的に(それを印刷することができるようにインタプリタは、式が並列コレクションビューである場合は、それを強制的に式を評価するので、ビューを強制する)。スタンドアロンのScalaプログラムとしてこれを実行しているいずれか試してみるか、次の操作を行います。

scala> object foo { var bar: AnyRef = null } 

scala> foo.bar = strList.par.view.filter{ s => println("f "+ tn); s == "I"}.map{s => println("m " + tn); s.toLowerCase} 

EDIT:

上記のもう一つの問題は、平行ビューでfilter方法である - 通常のビューとは異なり、それがコレクションを強制することにより実装されています。つまり、filterを並列viewにコールすると、フィルタリングされたコレクション全体が強制的に配列に入り、フィルタに関連付けられた述語を呼び出す必要があります。 groupByのようなメソッドは、通常のビューで同じことを行います。

+0

すみません、あなたの例は何ですか? –

+1

例のポイントは、パラレルビュー式をオブジェクトのフィールドに割り当てることによって、パラレルビューである右側の式をインタプリタで印刷するようにインタープリターを拒否した場合、インタプリタはビューを評価しません'力'を呼ぶ。ですから、 'filter'と' map'を呼び出すときに強制は起こりません。インタプリタでのみ起こるのは、ビューを出力する必要があるからです。これは、インタプリタがコレクションビューを特別に扱う( 'force'を避ける)が、並列コレクションビューを同じように扱うために特殊なケースではなかったためです。見落とし:) – axel22

+0

あなたは例が平行なビューではありません –