-1

Scala 2.9.2 ParSet zipWithIndex の興味深い動作を見つけました。これはバグなのか機能なのか疑問に思っていました。私はScalaの初心者なので、答えが明らかである場合は申し訳ありません。

これは、問題を示すセッションです。

Welcome to Scala version 2.9.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val x = Array(1,2,3,4,5,6,7,8)
x: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8)

// expected behavior

scala> x.toSet
res6: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 8, 4)

scala> x.toSet.zipWithIndex
res2: scala.collection.immutable.Set[(Int, Int)] = Set((1,1), (3,5), (4,7), (5,0), (6,2), (2,3), (8,6), (7,4))

// so far so good. let's try parallel implementation

scala> x.par.toSet
res0: scala.collection.parallel.immutable.ParSet[Int] = ParSet(5, 1, 6, 2, 7, 3, 8, 4)

// 
// 
// UNEXPECTED BEHAVIOR HERE
// 
scala> x.par.toSet.zipWithIndex
res1: scala.collection.parallel.immutable.ParSet[(Int, Int)] = ParSet((5,7), (6,5), (2,4), (1,6), (3,2), (4,0), (7,3), (8,1))

// just for good measure, this isn't an issue with Array or ParArray:
scala> x.zipWithIndex
res3: Array[(Int, Int)] = Array((1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6), (8,7))

scala> x.par.zipWithIndex
res7: scala.collection.parallel.mutable.ParArray[(Int, Int)] = ParArray((1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6), (8,7))

これは予想される動作ですか?ParSet の動作が Set と同等でないのはなぜですか?

4

1 に答える 1

0
  1. 要素の順序は、セットの定義 (実装固有の順序) では予想外です。実際に実行zipWithIndexすると、さまざまな実装でさまざまな順序が明らかになります。

    他のSet実装を使用すると、他の順序が得られ、それに応じてペアの他のセットが得られます(orderPos, element)

  2. 予期しない動作のもう 1 つの原因は、 http zipWithIndex: //docs.scala-lang.org/overviews/parallel-collections/overview.html#nonassociative_operationsの非関連性です。

    何度も実行するとx.par.toSet.zipWithIndex、時々異なる結果が得られると思います (おそらくより長いコレクションの場合)。

    更新しました

    私はそれを数回実行しました:

    scala>  x.par.toSet.zipWithIndex
    res0: scala.collection.parallel.immutable.ParSet[(Int, Int)] = 
     ParSet((4,0), (8,1), (1,6), (6,5), (7,3), (5,7), (3,2), (2,4))
    
    scala>  x.par.toSet.zipWithIndex
    res1: scala.collection.parallel.immutable.ParSet[(Int, Int)] = 
     ParSet((4,0), (8,1), (6,5), (2,4), (3,3), (1,7), (7,2), (5,6))
    

    結果は異なります。

于 2013-09-09T06:30:46.877 に答える