2013-07-25 7 views
12

2.10 से पहले स्कैला में, मैं डिफ़ॉल्ट फर्कजॉइनपूल में समांतरता सेट कर सकता हूं (जैसा कि इस उत्तर में scala parallel collections degree of parallelism) है। स्कैला 2.10 में, वह एपीआई अब मौजूद नहीं है। यह अच्छी तरह से प्रलेखित है कि हम अपने कार्य समर्थन संपत्ति को असाइन करके एक संग्रह (http://docs.scala-lang.org/overviews/parallel-collections/configuration.html) पर समांतरता सेट कर सकते हैं।मैं स्कैला 2.10 समांतर संग्रहों के लिए थ्रेड की डिफ़ॉल्ट संख्या कैसे सेट करूं?

हालांकि, मैं अपने कोडबेस पर समानांतर संग्रह का उपयोग करता हूं और प्रत्येक संग्रह त्वरण में अतिरिक्त दो पंक्तियां जोड़ना नहीं चाहता हूं। क्या वैश्विक डिफ़ॉल्ट थ्रेड पूल आकार को कॉन्फ़िगर करने का कोई तरीका है ताकि someCollection.par.map(f(_)) स्वचालित रूप से थ्रेड की डिफ़ॉल्ट संख्या का उपयोग कर सके?

+1

यह मेरे सिर पर थोड़ा सा है, लेकिन स्कैला स्रोत कोड को देखते हुए मैंने कुछ देखा ... ऐसा लगता है कि समांतर संग्रह "डिफॉल्ट टास्कस्पोर्ट" पर अपनी रचना का आधार बनाते हैं, जिसे मुझे ओवरराइड करने का कोई तरीका नहीं दिखता है क्योंकि यह एक है वस्तु वैल https://github.com/scala/scala/blob/v2.10.2/src/library/scala/collection/parallel/package.scala – LaloInDublin

उत्तर

14

मुझे पता है कि सवाल एक महीने से अधिक पुराना है, लेकिन मेरे पास अभी भी वही प्रश्न है। गुगलिंग सहायक नहीं थी और मुझे कुछ भी नहीं मिला जो नई एपीआई में आधा रास्ते देखा।

सेटिंग -Dscala.concurrent.context.maxThreads = n जैसा कि यहां बताया गया है: Set the parallelism level for all collections in Scala 2.10? का कोई प्रभाव नहीं पड़ा, लेकिन मुझे यकीन नहीं है कि मैंने इसे सही तरीके से उपयोग किया है (मैं अपने आवेदन को 'जावा' के साथ पर्यावरण में चलाता हूं स्पष्ट रूप से स्थापित 'स्कैला' के बिना, यह कारण हो सकता है)।

मुझे नहीं पता कि स्कैला-लोगों ने उचित पैकेज ऑब्जेक्ट से इस आवश्यक सेटर को क्यों हटा दिया।

हालांकि, यह अक्सर प्रतिबिंब उपयोग करना संभव है एक अधूरी/अजीब इंटरफेस के आसपास काम करने के लिए:

scala.collection.parallel.`package` 
:

def setParallelismGlobally(numThreads: Int): Unit = { 
    val parPkgObj = scala.collection.parallel.`package` 
    val defaultTaskSupportField = parPkgObj.getClass.getDeclaredFields.find{ 
    _.getName == "defaultTaskSupport" 
    }.get 

    defaultTaskSupportField.setAccessible(true) 
    defaultTaskSupportField.set(
    parPkgObj, 
    new scala.collection.parallel.ForkJoinTaskSupport(
     new scala.concurrent.forkjoin.ForkJoinPool(numThreads) 
    ) 
) 
} 

स्काला के अधिक अस्पष्ट सुविधाओं से परिचित नहीं उन लोगों के लिए, यहाँ एक संक्षिप्त विवरण है

डिफ़ॉल्ट ऑब्जेक्ट के साथ पैकेज ऑब्जेक्ट का उपयोग करता है (यह जावा की स्थिर चर की तरह कुछ हद तक दिखता है, लेकिन यह वास्तव में पैकेज ऑब्जेक्ट का सदस्य चर है)। पहचानकर्ता के लिए बैकटीक्स की आवश्यकता होती है, क्योंकि package एक आरक्षित कीवर्ड है। फिर हमें वह निजी अंतिम क्षेत्र मिलता है जिसे हम चाहते हैं (getField ("defaultTaskSupport") किसी कारण से काम नहीं करता है? ...), इसे संशोधित करने में सक्षम होने के लिए इसे सुलभ होने के लिए कहें, और उसके बाद इसके मान को प्रतिस्थापित करें हमारे अपने फोर्कजोइन टास्क समर्थन।

मैं अभी तक समांतर संग्रहों के निर्माण की सटीक तंत्र को समझ नहीं पा रहा हूं, लेकिन कॉम्बिनेर विशेषता के स्रोत कोड से पता चलता है कि डिफ़ॉल्ट टास्क समर्थन का मान समानांतर संग्रहों को किसी भी तरह से समझा जाना चाहिए।

ध्यान दें कि सवाल एक पुराने प्रकार के प्रश्न के समान गुणात्मक रूप से है: "मेरे पास मेरे कोडबेस पर Math.random() है, मैं बीज को डीबगिंग उद्देश्यों के लिए एक निश्चित संख्या में कैसे सेट कर सकता हूं?" (उदाहरण देखें: Set seed on Math.random())। दोनों स्थितियों में, हमारे पास कुछ प्रकार के वैश्विक "स्थैतिक" चर हैं जो हम निश्चित रूप से दस लाख अलग-अलग स्थानों में उपयोग करते हैं, हम इसे बदलना चाहते हैं, लेकिन इस चर के लिए कोई सेटर्स नहीं हैं => हम प्रतिबिंब का उपयोग करते हैं।

नरक के रूप में बदसूरत, लेकिन ठीक काम करने लगता है। यदि आपको धागे की कुल संख्या सीमित करने की आवश्यकता है, तो यह न भूलें कि कचरा कलेक्टर अलग धागे पर चलता है।

+0

आप सौंदर्य! ठीक से ऐसा करने के लिए एक रास्ता तलाश रहे हैं। उम्मीद कर रहा था कि यह इतना बदसूरत नहीं होगा, लेकिन यह शायद ही आपकी गलती है। विचित्र रूप से अनुपयोगी इंटरफ़ेस दोष देना है। – itsbruce

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