所以我一直在使用Scala中的并行集合来处理我正在处理的图形项目,我已经定义了图形类的基础知识,它目前正在使用scala.collection.mutable.HashMap
,其中关键是Int
,值为ListBuffer[Int]
(邻接列表)。 (编辑:此后已更改为ArrayBuffer[Int]
std::vector<int, std::vector<int> >
。
我现在要做的是在图形中的所有顶点对之间运行一个度量,所以在C ++中我做了类似这样的事情:
// myVec = std::vector<int> of vertices
for (std::vector<int>::iterator iter = myVec.begin(); iter != myVec.end(); ++iter) {
for (std::vector<int>::iterator iter2 = myVec.begin();
iter2 != myVec.end(); ++iter2) {
/* Run algorithm between *iter and *iter2 */
}
}
我在Scala中做了同样的事情,并行化,(或尝试过):
// vertexList is a List[Int] (NOW CHANGED TO Array[Int] - see below)
vertexList.par.foreach(u =>
vertexList.foreach(v =>
/* Run algorithm between u and v */
)
)
C ++版本显然是单线程的,Scala版本有.par
所以它使用并行集合,并且在8个核心(同一台机器)上是多线程的。但是,C ++版本在大约3天的时间内处理了305,570对,而到目前为止,Scala版本在17个小时内仅处理了23,573对。
假设我正确地完成了math,单线程C ++版本比Scala版本快大约3倍。 Scala真的比C ++慢得多,或者我完全误用了Scala(我最近刚开始 - 我在Scala编程大约300页)?
谢谢! -kstruct
编辑要使用while循环,我可以执行类似..
的操作// Where vertexList is an Array[Int]
vertexList.par.foreach(u =>
while (i <- 0 until vertexList.length) {
/* Run algorithm between u and vertexList(i) */
}
}
如果你们的意思是对整个事情使用while循环,对于whiles是否有等效的.par.foreach
?
EDIT2 等一下,那段代码甚至不对 - 我的坏。如何使用while循环并行化这个?如果我有一些跟踪迭代的var i
,那么所有线程都不会共享i
吗?
答案 0 :(得分:4)
根据您的评论,我看到您在每个算法运行结束时更新共享的可变HashMap
。如果您随意进行散步,则共享Random
也是一个争用点。
我建议进行两项更改:
.map
和.flatMap
返回不可变集合,而不是修改共享集合。ThreadLocalRandom
(来自Akka或Java 7)减少对随机数生成器的争用pVertexList
和vertexList
。这样的事情:
val pVertexList = vertexList.par
val allResult = for {
u <- pVertexList
v <- pVertexList
} yield {
/* Run algorithm between u and v */
((u -> v) -> result)
}
值allResult
将为ParVector[((Int, Int), Int)]
。您可以在其上调用.toMap
将其转换为Map
。
答案 1 :(得分:2)
为什么可变?我不认为Scala 2.9.x上有一个很好的并行可变映射 - 特别是因为这样的数据结构被添加到即将到来的Scala 2.10中。
另一方面......你有List[Int]
?不要使用它,使用Vector[Int]
。另外,你确定你不是在其他地方浪费时间,从可变映射和缓冲区转换成不可变列表吗? Scala数据结构与C ++不同,因此您可能会遇到代码中其他地方的复杂性问题。
最后,当他询问争用时,我认为dave可能会出现问题。如果你有争用,并行可能会让事情变得更慢。如果不使其并行,它的运行速度/速度会更快/更慢?如果使它不平行使它更快,那么你很可能会遇到争用问题。
答案 2 :(得分:0)
我对此并不完全确定,但我认为foreach循环中的foreach循环相当慢,因为会创建大量对象。请参阅:http://scala-programming-language.1934581.n4.nabble.com/for-loop-vs-while-loop-performance-td1935856.html
尝试使用while循环重写它。
此外,列表仅对头部访问有效,阵列可能更快。