Scala最有效的运算符添加到列表中

时间:2015-06-26 15:07:18

标签: scala

通过逐步修改scala列表来构建它。什么是最有效的“添加”运算符?在CPU和资源消耗方面。

例如,从List(1,2,3)我们想要创建一个连续数字元组的列表。结果如下:List((1,2),(2,3))

方法1 - 使用:+运算符

def createConsecutiveNumPair1[T](inList: List[T]) : List[(T, T)] = {
  var listResult = List[(T, T)]()
  var prev = inList(0)
  for (curr <- inList.tail)
  {
    listResult = listResult :+ (prev, curr)
    prev = curr
  }
  listResult
}

方法2 - 使用:: =运算符

def createConsecutiveNumPair2[T](inList: List[T]) : List[(T, T)] = {
  var listResult = List[(T, T)]()
  var prev = inList(0)
  for (curr <- inList.tail)
  {
    listResult ::= (prev, curr)
    prev = curr
  }
  listResult
}

TEST

scala> val l1 = List(1,2,3)
l1: List[Int] = List(1, 2, 3)

scala> createConsecutiveNumPair1(l1)
res77: List[(Int, Int)] = List((1,2), (2,3))

scala> createConsecutiveNumPair2(l1)
res78: List[(Int, Int)] = List((2,3), (1,2))

问题:哪个运营商的CPU资源消耗最低?如果你能提出一个更好的scala方法来重写上面的方法,也会很感激。

2 个答案:

答案 0 :(得分:3)

第一个代码的问题在于它附加O(n) List。所以算法基本上是O(n^2)

前置List非常有效,因为它以恒定时间O(1)运行,您可以在第二个算法中执行此操作。您可以使用它并在最后执行reverse以使两个方法的结果相等,这大致使其在O(n)中运行。

然而,库中已经有一个很好的方法可以满足您的需求。 sliding正是您要找的。滑动参数定义了元组的大小。

这会给你一个List[List[Int]]

List(1,2,3,4).sliding(2).toList  //List(List(1,2), List(2,3), List(3,4))

如果您坚持使用元组,则可以另外使用collectmap。请注意,当列表只有一个元素时,map将抛出异常。

List(1,2,3,4).sliding(2).collect{
  case List(a,b) => (a,b)
}.toList                        //List((1,2), (2,3), (3,4))

答案 1 :(得分:1)

这些方法通常只是相互调用(虽然检查实现是否确定)。 List是一个单链接列表,针对访问头部而不是尾部进行了优化,因此向前端而不是末尾添加元素要高效得多。如果您想在列表末尾访问/添加元素,最好使用Vector代替。

(与往常一样,如果您一直在问这个问题,那么您应该使用自动化工具来告诉您答案。如果您不使用分析器来告诉您应用的哪些部分它很慢,不值得花时间在这种微观优化上 - 你几乎肯定会优化错误的部分。)