填充列表是Scala,随机双重占用

时间:2011-03-14 20:22:37

标签: performance list scala

我是Scala的新手,正在尝试获取随机双值列表:

问题是,当我尝试运行它时,与Java对应物相比,它需要的时间太长。关于为什么会这样或有关更有效方法的建议的任何想法?

def random: Double = java.lang.Math.random()
var f = List(0.0)
for (i <- 1 to 200000)
 ( f = f ::: List(random*100)) 
 f = f.tail

7 个答案:

答案 0 :(得分:21)

你也可以这样做:

List.fill(200000)(math.random)

同样适用于数组......

Array.fill(200000)(math.random)
等等......

答案 1 :(得分:9)

你可以构建一个无限的随机双打流:

def randomList(): Stream[Double] = Stream.cons(math.random, randomList)

val f = randomList().take(200000)

这将利用延迟评估,因此在您真正需要之前不会计算值。即使评估所有200,000,也会很快。另外,f不再需要var

答案 2 :(得分:7)

另一种可能性是:

val it = Iterator.continually(math.random)
it.take(200000).toList
如果您愿意,

Stream也有continually方法。

答案 3 :(得分:5)

首先,它没有比java更长的时间,因为没有java对应物。 Java没有不可变列表。如果确实如此,表现将大致相同。

其次,由于附加列表具有线性性能,因此花费了大量时间,因此整个事物具有二次性能。

而不是附加,前置,具有持续的性能。

答案 4 :(得分:4)

如果你使用可变状态,你应该使用像缓冲区这样的可变集合,你也可以用+=添加它(那时它将是真正的对应于java代码)。

但为什么不使用列表理解?

val f = for (_ <- 1 to 200000) yield (math.random * 100)

顺便说一下:var f = List(0.0) ... f = f.tail可以在您的示例中替换为var f: List[Double] = Nil。 (没有更多的表现,但更美丽;)

答案 5 :(得分:2)

还有更多选择!尾递归:

def randlist(n: Int, part: List[Double] = Nil): List[Double] = {
  if (n<=0) part
  else randlist(n-1, 100*random :: part)
}

或映射范围:

(1 to 200000).map(_ => 100*random).toList

答案 6 :(得分:1)

看起来您想要使用Vector而不是List。列表有O(1)前置,Vector有O(1)追加。由于您要附加,但使用连接,使用Vector会更快:

def random: Double = java.lang.Math.random()
var f: Vector[Double] = Vector()
for (i <- 1 to 200000)
  f = f :+ (random*100)

知道了吗?