ठीक है, यह एक मूर्ख सवाल हो सकता है, लेकिन अभिनेता ढांचे के भीतर समांतर संग्रह का उपयोग करने का क्या फायदा है? यही है, अगर मैं केवल एक अभिनेता के मेलबॉक्स से एक संदेश से निपट रहा हूं, तो समानांतर संग्रह की आवश्यकता भी है? समांतर संग्रह और कलाकार पारस्परिक रूप से अनन्य हैं? एक उपयोग केस क्या है जिसमें दोनों शामिल होंगे?स्कैला 2.9 में समांतर संग्रह और अभिनेता
उत्तर
वे विभिन्न समस्याओं को हल करते हैं। task parallel problems को हल करने में अभिनेता अच्छे हैं। जबकि समानांतर संग्रह data parallel problems को हल करने में अच्छे हैं। मुझे नहीं लगता कि वे पारस्परिक रूप से अनन्य हैं - आप अभिनेताओं और कलाकारों समांतर समांतर संग्रहों में समांतर संग्रह का उपयोग कर सकते हैं।
संपादित करें - त्वरित परीक्षण: यहां तक कि कुछ एक अभिनेता अधिसूचना पाश लाभ की तरह सरल।
निम्नलिखित कोड में हम एक अभिनेता रजिस्ट्री के साथ एक मिलियन अभिनेता पंजीकृत करते हैं जिन्हें उन्हें किसी घटना के बारे में सूचित करना होता है।
गैर समांतर अधिसूचना पाश (registry foreach {}
) मेरी मशीन (2. कोर 2.5 गीगाहर्ट्ज नोटबुक) पर औसतन 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")
}
अभिनेता पुस्तकालय, सिर्फ विकल्पों में से एक है कई (धागे & ताले, एसटीएम, वायदा/वादों) के बीच, संगामिति दृष्टिकोण है, और यह समस्याओं के सभी प्रकार के लिए इस्तेमाल किया जाना चाहिए नहीं कर रहा है, या सब कुछ के साथ संयोजन करने के लिए (हालांकि अभिनेता और एसटीएम एक साथ एक अच्छा सौदा कर सकता है)। कुछ मामलों में, कलाकारों (समूह + पर्यवेक्षक) का समूह स्थापित करना या फोर्क-जॉइन पूल में उन्हें खिलाने के लिए स्पष्ट रूप से भागों में एक कार्य को विभाजित करना, बहुत बोझिल है, और यह मौजूदा पर .par
पर कॉल करने का एकमात्र तरीका है संग्रह जो आप पहले से ही उपयोग कर रहे हैं, और इसे समानांतर में पार करते हैं, लगभग एक प्रदर्शन लाभ प्राप्त करने के लिए लगभग (सेटअप के मामले में)।
सब कुछ, अभिनेता और समांतर संग्रह समस्या के विभिन्न आयाम हैं - कलाकार एक समवर्ती प्रतिमान है, जबकि समानांतर संग्रह केवल एक उपयोगी उपकरण है जिसे एक समवर्ती विकल्प के रूप में नहीं देखा जाना चाहिए, बल्कि इसके संवर्धन के रूप में संग्रह टूलसेट।
इस पर आपके परिप्रेक्ष्य के लिए धन्यवाद। यह समझ में आता है। –
आपके उत्तर के लिए धन्यवाद। मैं देख सकता हूं कि एक * * कलाकारों के भीतर समानांतर संग्रह का उपयोग कर सकता है, लेकिन ऐसा लगता है कि इस मामले में नियमित संग्रह का उपयोग करने से यह और अधिक फायदेमंद नहीं होगा। एक समानांतर संग्रह का उपयोग करने का विचार, जिसमें अभिनेता शामिल हैं, दूसरी ओर, एक उपयोगी चीज की तरह लगता है। मुझे वह विचार पसंद है। मुझे विचार के लिए भोजन देने के लिए धन्यवाद ... –
कुछ परीक्षण कोड बनाने के लिए धन्यवाद, यह बहुत अच्छा है! मैं वास्तव में इसकी प्रशंसा करता हूँ। –
@ ब्रूस। ध्यान दें कि समानांतर संग्रहों का उपयोग करने का एक और मौका है - ऊपर दिए गए कोड में इनिट लूप करने के लिए लगभग 12 सेकंड लगते हैं। अगर हम समानांतर होते हैं कि इसमें लगभग 4 सेकंड लगते हैं ((1 से 1000000) .par.foreach {i => ...})। –