Scala Filter和Collect很慢

时间:2016-08-09 10:14:12

标签: performance scala optimization filter collect

我刚开始使用Scala开发,并尝试使用filter和collect从迭代器中过滤掉不必要的行。但操作似乎太慢了。

val src = Source.fromFile("/home/Documents/1987.csv") // 1.2 Million
val iter = src.getLines().map(_.split(":"))
val iter250 = iter.take(250000) // Only interested in the first 250,000

val intrestedIndices = range(1, 100000, 3).toSeq // This could be any order

val slicedData = iter250.zipWithIndex

// Takes 3 minutes
val firstCase = slicedData.collect { case (x, i) if intrestedIndices.contains(i) => x }.size 

// Takes 3 minutes
val secondCase = slicedData.filter(x => intrestedIndices.contains(x._2)).size 

// Takes 1 second
val thirdCase = slicedData.collect { case (x,i ) if i % 3 == 0 => x}.size   

似乎intrestedIndices.contains(_)部分正在减慢第一和第二种情况下的程序。是否有其他方法可以加快这一过程。

2 个答案:

答案 0 :(得分:1)

这个答案有助于解决问题。

您在前两种情况下以线性时间迭代所有interestIndices。使用Set而不是Seq来提高性能 - Sergey Lagutin

答案 1 :(得分:0)

对于记录,这里有一个方法来过滤一个(有序的)索引Seq,不一定是等距的,而不是在每一步扫描索引:

def filterInteresting[T](it: Iterator[T], indices: Seq[Int]): Iterator[T] =
  it.zipWithIndex.scanLeft((indices, None: Option[T])) {
    case ((indices, _), (elem, index)) => indices match {
      case h :: t if h == index => (t, Some(elem))
      case l => (l, None)
    }
  }.map(_._2).flatten