`zipWithIndex`与否:我们获得了多少收益?

时间:2015-06-23 17:17:42

标签: scala

假设我有case class SamplePair( arrayOfNumbers: ArrayBuffer[Int] ) 用于某种目的。

sequenceOfSamplePair

假设我Seq有一个基本SamplePair的{​​{1}},我想在每个元素的arrayOfNumbers元素中添加一些有序数字。

一种方法是这样做:

val ctr = new AtomicInteger(0)
sequenceOfSamplePair.foreach{ entry => 
   entry.arrayOfNumbers += ctr.getAndIncrement()
}

另一种方法是使用zipWithIndex执行此操作。

sequenceOfSamplePair.zipWithIndex.foreach {
      case (entry, ctr) =>
        entry.arrayOfNumbers += ctr
 }

使用zipWithIndex更喜欢实施的原因是什么?是否更多"功能性"?

2 个答案:

答案 0 :(得分:2)

由于您的两种方法都不起作用,我会选择第一种方法。 在第二种方法中,您将功能构造与命令式构造混合在一起,而您却失去了从功能性解决方案中获得的所有收益。

在案例类中使用可变缓冲区也不能使用可变缓冲区。

更具功能性的方法可能看起来像

case class SamplePair(numbers: List[Int])

val extendedSequenceOfSamplePair = sequenceOfSamplePair.zipWithIndex.map {
  case ( sp@SamplePair(oldNumbers), idx) => sp.copy( numbers = idx :: oldNumbers)
}

答案 1 :(得分:2)

我刚用这两种方法做了一些分析。没有明显的赢家。如果zipWithIndex中的模式匹配替换为直接引用(_1_2),那么它会稍微快一点,但仍然不是明显的赢家。

但是,如果你使用如下流媒体:

Stream.range(0, sequenceOfSamplePair.length).map { i =>
  sequenceOfSamplePair(i) += i
}
那么,它的速度提高了约6倍。这是因为它非常简单,只需逐个通过柜台,直接添加到数字。 6x速度要快得多,这意味着getAndIncrement似乎使相对而言非常非常慢。