0

Which one is faster performance wise. How can a view make it faster in this case?

def f(arr: List[Int]): List[Int] =
  arr.zipWithIndex.filter(_._2 % 2 == 1).map(_._1)

def f(arr: List[Int]): List[Int] =
  arr.view.zipWithIndex.filter { _._2 % 2 != 0 }.map(_._1).toList

def f(arr: List[Int]): List[Int] =
  arr.view.zipWithIndex.collect { case (a, b) if (b % 2 == 0) => a }.toList
Sam
  • 497
  • 1
  • 10
  • 34
  • 2
    Technically speaking, the only way to tell would be to benchmark with a use case similar to the one that really matters for you. But, theoretically speaking, either the second or the third one _should_ be faster than the first because they are lazy, thus they apply all the transformations in one iteration. _(I would go for the third one because I prefer `collect` than `filter ` + `map`, but that is just style)_. - Note: it would be better to use **Iterator** instead of **View**, if you are in `2.12` **Views** are broken and on `2.13` **Views** are correct but **Iterators** are slightly faster. – Luis Miguel Mejía Suárez Dec 06 '19 at 20:28
  • If you need speed (micro optimization), you should use arrays. If you don't want it, use one of simplest way. I think you should not think about micro optimization, specially in this case. Premature optimization is root of all evil. – Mikhail Ionkin Dec 07 '19 at 09:07

1 Answers1

0
def f(arr: List[Int]): List[Int] =
  arr.grouped(2).flatMap(_.drop(1)).toList

:)


More seriously:

def f(arr: List[Int]): List[Int] = {
  @annotation.tailrec
  def loop(rem: List[Int], res: List[Int]): List[Int] =
    rem match {
      case _::b::tail => loop(tail, b +: res)
      case _ => res.reverse
    }

  loop(arr, Nil)
}
Tim
  • 26,753
  • 2
  • 16
  • 29
  • Please add some explanation to your answer. I cannot see how you answered the question "Which one of these three functions is the fastest" after all – Nico Haase Dec 07 '19 at 13:20