好吧,這可能是一個相當愚蠢的問題,但是在一個actor框架中使用並行集合有什麼好處?也就是說,如果我只從一個演員的郵箱中處理一條消息,是否還需要一個並行收集?平行收藏和演員是相互排斥的嗎?什麼是涉及兩者的用例?Scala 2.9和Actor中的並行集合
回答
他們解決了不同的問題。演員擅長解決task parallel problems。儘管並行收集很好地解決了data parallel problems。我不認爲它們是相互排斥的 - 你可以在包含演員的演員和平行集合中使用平行集合。
編輯 - 快速測試: 即使是一些簡單的像一個演員的通知循環的好處。
在下面的代碼中,我們向一個演員註冊表註冊了一百萬個演員,他們必須通知他們一個事件。
非並行通知循環(registry foreach {}
)在我的機器(4核2.5 GHz筆記本)上平均需要2.8秒。 使用並行採集循環(registry.par.foreach {}
)時,需要1.2秒鐘,並使用全部四個核心。在斯卡拉
import actors.Actor
case class Register(actor: Actor)
case class Unregister(actor: Actor)
case class Message(contents: String)
object ActorRegistry extends Actor{
var registry: Set[Actor] = Set.empty
def act() {
loop{
react{
case reg: Register => register(reg.actor)
case unreg: Unregister => unregister(unreg.actor)
case message: Message => fire(message)
}
}
}
def register(reg: Actor) { registry += reg }
def unregister(unreg: Actor) { registry -= unreg }
def fire(msg: Message){
val starttime = System.currentTimeMillis()
registry.par.foreach { client => client ! msg } //swap registry foreach for single th
val endtime = System.currentTimeMillis()
println("elapsed: " + (endtime - starttime) + " ms")
}
}
class Client(id: Long) extends Actor{
var lastmsg = ""
def act() {
loop{
react{
case msg: Message => got(msg.contents)
}
}
}
def got(msg: String) {
lastmsg = msg
}
}
object Main extends App {
ActorRegistry.start
for (i <- 1 to 1000000) {
var client = new Client(i)
client.start
ActorRegistry ! Register(client)
}
ActorRegistry ! Message("One")
Thread.sleep(6000)
ActorRegistry ! Message("Two")
Thread.sleep(6000)
ActorRegistry ! Message("Three")
}
Actors庫只是其中一個選項,接近並行,許多(線程&鎖,STM,期貨/承諾)之一,它不應該被用於各種各樣的問題,或可以與所有東西組合(雖然演員和STM可以在一起做出很好的交易)。在某些情況下,建立一組演員(工作人員+監督員)或明確地將任務分成若干部分並將它們饋送到叉式連接池太繁瑣,而且在現有設備上調用.par
你已經在使用這個集合,並且簡單地在並行中進行遍歷,幾乎可以免費獲得性能優勢(就設置而言)。
總而言之,參與者和並行集合是問題的不同維度 - 參與者是併發範例,而並行集合僅僅是一個有用的工具,應該將其視爲不是並行選擇,而是作爲集合工具集。
感謝您對此的看法。這說得通。 – 2011-04-10 22:57:34
- 1. 如何替換Scala 2.9並行集合的分支連接池?
- 2. Scala中的並行處理2.9
- 3. scala並行集合並行度
- 4. 如何在Scala Actor中合併或跳過重複的郵件?
- 5. Scala 2.9中的settings.maxPrintString REPL
- 6. Scala並行集合上的哪些操作是並行化的?
- 7. 覆蓋scala中的默認並行集合行爲
- 8. 在Scala中合併巨集(HashSet)
- 9. Scala並行集合:如何知道和配置線程數
- 10. Scala:如何合併地圖集合
- 11. Scala.io指南和Scala 2.9簡單IO?
- 12. Scala Remote Actor安全
- 13. 如何控制scala並行集合上的併發
- 14. Scala並行集合中每個項目的發生次數
- 15. 爲Scala 2.10中的所有集合設置並行性級別?
- 16. 如何將mapValues轉換爲Scala中的並行集合
- 17. Scala 2.9.x中的XML支持狀態
- 18. 在Scala上查詢2.9
- 19. JSF中的Scala集合
- 20. Scala類中的集合
- 21. Scala中的排序集合
- 22. 在集合中存儲Akka actor的框架
- 23. Scala集合串
- 24. 如何限制在Scala中使用actor時的併發性?
- 25. 在scala中mergesort的合併
- 26. Scala的死鎖具有平行集合
- 27. 意外的Scala集合記憶行爲
- 28. 如何避免使用scala並行集合的競爭條件
- 29. 如何設置Scala 2.10並行集合的默認線程數?
- 30. Java中有沒有與Scala中的並行集合接近的東西?
感謝您的回答。我可以看到一個* CAN *可以在演員中使用平行集合,但似乎並不比在這種情況下使用常規集合更有利。另一方面,使用包含演員的平行集合的想法看起來很有用。我喜歡這個想法。謝謝你給我一些想法... – 2011-04-10 18:10:33
感謝你創建一些測試代碼,這太棒了!對此,我真的非常感激。 – 2011-04-11 15:17:20
@Bruce。注意在這裏有另一個使用並行集合的機會 - 上面的代碼需要大約12秒來完成init循環。如果我們並行化了大約4秒((1到1000000).par.foreach {i => ...})。 – 2011-04-11 17:07:40