我发现Scala 2.9.2 ParSet zipWithIndex有一些有趣的行为,我想知道这是一个bug还是一个功能。如果答案很明显,我很抱歉,因为我是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?
答案 0 :(得分:0)
通过定义集合 - 元素的顺序是意外的 - 特定于实现的顺序。当你zipWithIndex
时,你实际上在不同的实现中揭示了不同的顺序。
如果您采用其他Set
实施,您将获得另一个订单,并相应地获得另一组(orderPos, element)
。
意外行为的另一个来源是zipWithIndex
的非关联性:
http://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))
结果不同。