首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >添加不可变向量

添加不可变向量
EN

Stack Overflow用户
提问于 2011-06-01 18:53:34
回答 3查看 2.6K关注 0票数 3

我正在尝试更多地使用scalas不可变集合,因为这很容易并行化,但我遇到了一些新手问题。我正在寻找一种从操作中(有效地)创建新的Vector的方法。准确地说,我想要的东西如下

代码语言:javascript
复制
val v : Vector[Double] = RandomVector(10000)
val w : Vector[Double] = RandomVector(10000)
val r = v + w

我测试了以下内容:

代码语言:javascript
复制
// 1)
val r : Vector[Double] = (v.zip(w)).map{ t:(Double,Double) => t._1 + t._2 }

// 2)
val vb = new VectorBuilder[Double]()    
var i=0
while(i<v.length){
  vb += v(i) + w(i)
  i = i + 1
}
val r = vb.result

}

与使用Array相比,这两种方法都需要很长时间:

代码语言:javascript
复制
[Vector Zip/Map   ] Elapsed time 0.409 msecs
[Vector While Loop] Elapsed time 0.374 msecs
[Array While Loop ] Elapsed time 0.056 msecs
// with warm-up (10000) and avg. over 10000 runs

有没有更好的方法呢?我认为使用zip/map/reduce的优势在于,只要集合支持这一点,它就可以并行运行。

谢谢

EN

回答 3

Stack Overflow用户

发布于 2011-06-01 22:06:54

Vector不是专门针对Double的,所以使用它会带来相当大的性能损失。如果您正在执行一个简单的操作,那么在单个核心上使用一个数组可能比在整台机器上使用Vector或其他通用集合要好(除非您有12+核心)。如果您仍然需要并行化,还可以使用其他机制,例如使用scala.actors.Futures.future创建实例,每个实例在范围的一部分上执行工作:

代码语言:javascript
复制
val a = Array(1,2,3,4,5,6,7,8)
(0 to 4).map(_ * (a.length/4)).sliding(2).map(i => scala.actors.Futures.future {
  var s = 0
  var j = i(0)
  while (j < i(1)) {
    s += a(j)
    j += 1
  }
  s
}).map(_()).sum  // _() applies the future--blocks until it's done

当然,您需要在一个更长的数组(以及具有四个内核的机器上)上使用它来进行并行化,以提高性能。

票数 5
EN

Stack Overflow用户

发布于 2011-06-01 20:36:39

当您使用多个高阶方法时,您应该使用延迟构建的集合:

代码语言:javascript
复制
v1.view zip v2 map { case (a,b) => a+b }

如果不使用视图或迭代器,每个方法都将创建一个新的不可变集合,即使不需要它们也是如此。

不可变的代码可能不会像可变的代码那样快,但惰性集合将大大改善代码的执行时间。

票数 4
EN

Stack Overflow用户

发布于 2011-06-01 22:53:30

数组不是类型擦除的,向量是类型擦除的。基本上,在处理无法克服的原语时,JVM为Array提供了优于其他集合的优势。Scala的specialization可能会降低这一优势,但考虑到它们在代码大小方面的成本,它们不可能在所有地方都使用。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6200005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档