scala的sliding window的多种实现和benchMark

需求

下午闲的写了点小代码来实现实现一个sliding window 效果的,并最终去平铺这些元素

[3 1 4 1 5 9]
[3,1]
[1,4]
[4,1]
[1,5]
[5,9]
[3,1,1,4,4,1,1,5,5,9]

思路

  1. 直接用init zip tail ,然后flatMap或者foldLeft
  2. 用java的方法通过index实现

代码

import java.time.{Duration, Instant}

/**
  * @author todd.chen at 9/23/16 1:33 PM.
  *         email : todd.chen@ximalaya.com
  */
object Test {
  def main(args: Array[String]): Unit = {
    val list = (1 to 1000000).map(i ⇒ i).toList
    val vectorList = list.toVector
    Thread sleep 5000

    (1 to 100).flatMap { i ⇒
      val first = benchMark(testIteratorBySam(list))
      val second = benchMark(testFlatList(list))
      val third = benchMark(testIterator(list))
      val purse = benchMark(testPurseJava(vectorList))
      Map("sam" → first, "list" → second, "iterator" → third, "pures" → purse)
    }.groupBy(_._1).map { case (k, v) ⇒
      k -> v.map(_._2).sum
    }.toSeq.sortBy(_._2).foreach(println)

    /*        val x = List(1, 2, 3, 4)
            testPurse(x).foreach(println)*/

  }


  def testPurseJava = (vectorList: Vector[Int]) ⇒ {
    val length = (vectorList.length - 1) * 2
    val result = new Array[Int](length)
    result(0) = vectorList.head
    (1 to vectorList.length - 2).foreach { i ⇒
      val x = vectorList(i)
      result(i * 2) = x
      result(i * 2 - 1) = x
    }
    result(length - 1) = vectorList.last
    result

  }

  def testFoldLeft = (xs: List[Int]) ⇒ {
    (xs.init zip xs.tail).foldLeft(List.empty[Int]) {
      case (ls, s) ⇒
        ls :+ s._1 :+ s._2
    }
  }


  def testIteratorBySam = (xs: List[Int]) ⇒ {
    (xs.init zip xs.tail).flatMap { l ⇒
      //l._1 :: l._2 :: Nil
      //l.productIterator
      new Iterator[Int]() {
        var f: Boolean = true

        override def hasNext: Boolean = f

        override def next(): Int = if (f) {
          f = false
          l._1
        } else {
          l._2
        }
      }
    }
  }

  def testFlatList = (xs: List[Int]) ⇒ {
    (xs.init zip xs.tail).flatMap { l ⇒
      l._1 :: l._2 :: Nil
    }
  }

  def testIterator = (xs: List[Int]) ⇒ {
    (xs.init zip xs.tail).flatMap { l ⇒
      //      l._1 :: l._2 :: Nil
      l.productIterator
    }
  }

  def benchMark(testFunc: ⇒ Traversable[Any]) = {
    val start = Instant.now()
    testFunc
    val end = Instant.now()
    Duration.between(start, end).toNanos
  }
}

结果

java版的效果很好,然后是我的leader sam给出的,接着是直接调用productorIterator,最后是flatMap的list,而foldLeft性能太差了

你可能感兴趣的:(scala)