2012-01-17 17 views
5

में पाइप-लाइन प्रोसेसिंग का उपयोग करने जैसे एक दूसरे के साथ समानांतर प्रदर्शन करते हैं, मुझे मेरी खराब अंग्रेजी क्षमा करें लेकिन मैं अपना प्रश्न व्यक्त करने के लिए अपना सर्वश्रेष्ठ प्रयास करूंगा।क्या हम स्केल में डीएसएल ऑपरेशन का एक सेट परिभाषित कर सकते हैं जो लिनक्स

मान लीजिए कि मैं एक बड़े पाठ को संसाधित करना चाहता हूं जिसका ऑपरेशन कुंजी शब्द के माध्यम से सामग्री फ़िल्टर करना है; उन्हें लोअरकेस में बदलें; और फिर उन्हें मानक आउटपुट पर प्रिंट करें।

cat article.txt | grep "I" | tr "I" "i" > /dev/stdout 

जहां cat article.txt, grep "I", tr "I" "i" > /dev/stdout समानांतर में चल रहे हैं: हम सभी जानते हैं, हम लिनक्स bash स्क्रिप्ट में इस पाइप लाइन का उपयोग कर सकते हैं।

स्काला में, हम शायद यह इस तरह कार्य करें:

//or read from a text file , e.g. article.txt 
val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") 
strList.filter(_ == "I").map(_.toLowerCase).foreach(println) 

मेरा प्रश्न है कि हम कैसे filter, map और foreach समानांतर कर सकते है?

thx

+1

प्रश्न अधिक समझ में नहीं आता है। बैश स्क्रिप्ट समानांतर में नहीं चल रहा है। – soc

उत्तर

2

2.9 में, समांतर संग्रह जोड़े गए थे। लूप को समानांतर करने के लिए, आपको केवल par सदस्य फ़ंक्शन को कॉल करके इसे परिवर्तित करना है।

आपका कोड इस तरह दिखेगा:

val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") // or read from a text file , e.g. article.txt 
strList.par.filter(_ == "I").map(_.toLowerCase).foreach(println)
+0

'par' बस संग्रह को समानांतर प्रकार में बदलें। हालांकि संग्रह का प्रत्येक कार्य समानांतर है लेकिन एक साथ समूह के साथ एक-दूसरे के साथ नहीं। कहें, 'strList.par' स्ट्रेलिस्ट समानांतर बनाता है, लेकिन' फ़िल्टर', 'मानचित्र' और 'foreach' को एक-एक करके बुलाया जाता है, प्रत्येक फ़ंक्शन –

+0

में समानांतर ऑपरेशन होता है,' ''' ' फ़िल्टर 'आपके उदाहरण में खत्म होता है। मैं जो चाहता हूं वह यह है कि 'फ़िल्टर',' मैप 'और' फोरैच 'समानांतर चल रहा है, एक-एक करके नहीं, बस लिनक्स –

+1

में पाइपलाइन की तरह स्पष्टीकरण के लिए, क्या आप प्रत्येक ऑपरेशन से डेटा प्रवाह के रूप में प्रवाह करना चाहते हैं? तो बिल्ली grep में स्ट्रीम कर रही है जो tr आदि से बाहर निकलती है। यदि ऐसा है, तो क्या यह एक ऐसे फ़ंक्शन को लिखने के लिए अधिक कुशल नहीं होगा जो मूल संग्रह को फ़िल्टर/मानचित्र करता हो? –

2

आप एक इटरेटर करने के लिए अपने सूची को बदलते हैं तो आप देखेंगे कि फिल्टर/मानचित्र/foreach अब और समूहबद्ध नहीं हैं।

इस प्रयास करें:

val strList = Iterator("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") 
strList.filter{ s => println("f"); s == "I"}.map{s => println("m"); s.toLowerCase}.foreach{s =>println("p")} 

आप देखेंगे:
च मीटर पी च च च च च मीटर पी च च च च च एम पी च च

बजाय

: च च च च च च च च च च च च च मीटर मीटर मीटर पी पी पी

क्योंकि जब आप किसी सूची में परिवर्तन लागू करते हैं, तो यह तुरंत एक नई सूची देता है। लेकिन जब एक इटरेटर में परिवर्तन लागू होता है, तो यह केवल तभी चलाया जाएगा जब आप इसे पार करते हैं (इस मामले में foreach के साथ)।

+0

के समान होने के लिए डीएसएल के एक सेट को परिभाषित कर सकते हैं, हालांकि, यह फ़िल्टर और मानचित्र का समानांतर निष्पादन नहीं है। दोनों अभी भी एक ही थ्रेड द्वारा निष्पादित कर रहे हैं। –

+1

@ स्टीफन, वास्तव में, लेकिन tstenner के जवाब पर उनकी टिप्पणी से मुझे लगता है कि यह वह व्यवहार हो सकता है जिसे वह ढूंढ रहा है, जरूरी नहीं कि बहु-थ्रेडेड निष्पादन। – hbatista

+0

thx, यही वह व्यवहार है जिसे मैं ढूंढ रहा हूं, लेकिन बेहतर होगा अगर यह बहु-थ्रेडेड निष्पादन –

0

कार्यों की अपनी श्रृंखला से एक तर्क के लिए एक फ़ंक्शन बनाएं। फिर इस फ़ंक्शन को समांतर संग्रह पर लागू करें। ध्यान दें कि मूल संग्रह के क्रम में println नहीं कहा जाएगा।

def fmp(xs: Seq[String]){ 
    xs.par.foreach{x => 
    for(
     kw <- Option(x).filter(_ == "I"); 
     lc <- kw.map(_.toLowerCase) 
    ) println(lc) 
    } 
} 
2

tstenner के समाधान शायद अपनी स्थिति में सबसे अधिक दक्षता समाधान है, क्योंकि यह समानांतरवाद के एक उच्च स्तर (प्रत्येक एकल आइटम सैद्धांतिक रूप से समानांतर में संसाधित किया जा सकता है) प्राप्त कर सकते हैं। हालांकि, आपका बैश उदाहरण केवल पाइपलाइन समांतरता का उपयोग कर रहा है और दुर्भाग्य से इस तरह की समांतरता स्केलस समांतर संग्रहों द्वारा सीधे समर्थित नहीं है।

पाइपलाइन समांतरता प्राप्त करने के लिए आपके ऑपरेटरों (फ़िल्टर, मानचित्र, foreach) को विभिन्न धागे द्वारा निष्पादित किया जाना चाहिए, उदाहरण के लिए, अभिनेताओं का उपयोग करके।

आम तौर पर मुझे लगता है कि स्कैला के लिए एक साधारण एपीआई होना अच्छा होगा। लेकिन, आपके उदाहरण के लिए मुझे संदेह है कि पाइपलाइन समांतरता आपके निष्पादन समय को तेज़ कर देगी। यदि आप बस बहुत ही सरल फ़िल्टर और मैप ऑपरेशंस का उपयोग करते हैं तो मुझे लगता है कि संचार ओवरहेड (एफआईएफओ/अभिनेता मेलबॉक्स के लिए) आपके समांतर निष्पादन की पूरी गति का उपभोग करता है।

+0

बन जाए तो क्या हमें स्केल विकास टीम को भविष्य में ऐसी पाइपलाइन समांतरता एपीआई प्रदान करने की सलाह देनी चाहिए, उदाहरण के लिए 2.11 संस्करण –

+0

निश्चित रूप से उपयोगी होगा, हां। लेकिन यह भी लागू करना मुश्किल नहीं है। मैंने इसे अपने शोध प्रोजेक्ट (मैशप फ्रेमवर्क) के लिए मैप, फ्लैटमैप, फ़िल्टर, ग्रुपबी, और कम करने वाले ऑपरेटरों के साथ कार्यान्वित किया। अगर मुझे कोड ओपन सोर्स को रिलीज़ करने की इजाजत है (संभवतः अप्रैल से पहले नहीं) तो मैं एक और टिप्पणी छोड़ दूंगा। –

+0

उत्तर वास्तव में समझ में नहीं आता है। बैश स्क्रिप्ट में बिल्कुल समानांतर गणना नहीं है। यह ध्यान में रखते हुए कि आप एक फ़ाइल से पढ़ते हैं और प्रसंस्करण तुच्छ से अधिक है, मुझे समानांतर बनाने में कोई कारण या लाभ नहीं दिखता है (जिसे '.par' जोड़कर बहुत आसानी से किया जाता है)। – soc

2

एक दृश्य का उपयोग करें:

val strList = List("I", "am", "a" , "student", ".", "I", "come", "from", "China", ".","I","love","peace") // or read from a text file , e.g. article.txt 
strList.view.filter(_ == "I").map(_.toLowerCase).foreach(println) 

दृश्य संग्रह (filter और map इस मामले में) पर कार्रवाई की दुकान और उन्हें अमल आप (इस मामले में foreach) उन लोगों से तत्वों का अनुरोध केवल जब। तो सबसे पहले यह "I" पर फ़िल्टर और मानचित्र लागू करेगा, फिर "am", और इसी तरह।

+0

thx, यह इटरेटर का उपयोग कर एक ही प्रभाव मिलता है –

संबंधित मुद्दे