2011-02-16 13 views
18

pmap फ़ंक्शन पर प्रलेखन मुझे आश्चर्यचकित करता है कि वेब पर XML फ़ीड्स का संग्रह लाने जैसे कुछ के लिए यह कितना कुशल होगा। मुझे नहीं पता कि कितने समवर्ती fetch ऑपरेशन pmap पैदा होगा और अधिकतम क्या होगा।यूआरएल-फ़ेचिंग ऑपरेशंस के लिए क्लोजर के pmap फ़ंक्शन कितने थ्रेड हैं?

उत्तर

18

आप स्रोत की जाँच यदि आप देखते हैं:

> (use 'clojure.repl) 
> (source pmap) 
(defn pmap 
    "Like map, except f is applied in parallel. Semi-lazy in that the 
    parallel computation stays ahead of the consumption, but doesn't 
    realize the entire result unless required. Only useful for 
    computationally intensive functions where the time of f dominates 
    the coordination overhead." 
    {:added "1.0"} 
    ([f coll] 
    (let [n (+ 2 (.. Runtime getRuntime availableProcessors)) 
     rets (map #(future (f %)) coll) 
     step (fn step [[x & xs :as vs] fs] 
       (lazy-seq 
       (if-let [s (seq fs)] 
        (cons (deref x) (step xs (rest s))) 
        (map deref vs))))] 
    (step rets (drop n rets)))) 
    ([f coll & colls] 
    (let [step (fn step [cs] 
       (lazy-seq 
       (let [ss (map seq cs)] 
        (when (every? identity ss) 
        (cons (map first ss) (step (map rest ss)))))))] 
    (pmap #(apply f %) (step (cons coll colls)))))) 

(+ 2 (.. Runtime getRuntime availableProcessors)) एक बड़ा सुराग नहीं है। pmap पहले (+ 2 processors) काम के टुकड़े ले जाएगा और उन्हें future के माध्यम से असीमित रूप से चलाएगा। तो यदि आपके पास 2 कोर हैं, तो यह एक समय में 4 टुकड़े काम शुरू करने जा रहा है, आपसे थोड़ा आगे रखने की कोशिश कर रहा है लेकिन अधिकतम 2 + एन होना चाहिए।

future अंततः एजेंट आई/ओ थ्रेड पूल जो धागे की एक असीम संख्या का समर्थन करता है का उपयोग करता है। यह बढ़ेगा क्योंकि उस पर काम फेंक दिया गया है और धागे का उपयोग नहीं किया जाता है।

कि कैसे pmap काम करता है बताते हैं
+1

तो क्या संक्षिप्त उत्तर है कि 'pmap' बहुत सारी वेब कॉल भेजने और प्रतिक्रियाओं को संसाधित करने के लिए बिल्कुल ठीक है? क्या कोई चेतावनी है? – dan

+4

मैं गलत हो सकता हूं, लेकिन मुद्दा शायद यह होगा कि एन + 2 धागे वेब प्रतिक्रियाओं के लिए इंतजार कर रहे हैं। तो आपको अधिकतम थ्रूपुट के लिए पर्याप्त इन-फ्लाइट अनुरोध नहीं मिलेगा - pmap वास्तव में CPU-bound वर्कलोड के लिए है। यदि यह आपके साथ हो रहा है, तो आप भविष्य में प्रत्येक अनुरोध कॉल को केवल लपेट सकते हैं और वे सभी एक बार में उड़ जाएंगे। – mikera

+4

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

9

बिल्डिंग एलेक्स के उत्कृष्ट जवाब पर, यहाँ अपनी स्थिति के लिए मेरे सुझाव है:

(doall 
    (map 
    #(future (my-web-fetch-function %)) 
    list-of-xml-feeds-to-fetch)) 

दलील:

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

मुझे लगता है कि वायदा एक असंबद्ध थ्रेड पूल का उपयोग करते हैं, इसलिए फ़ीड के बड़े संग्रह पर इसे चलाने से समस्याएं पैदा हो सकती हैं। – Glen

+1

इसके अलावा, आप संभवतः फिर से वायदा को 'deref'' पर मैप करना चाहते हैं ताकि आपको पता चल जाए कि सबकुछ खत्म हो गया है। – Joe

3

कोई समय कोई लंबा जवाब लिखने के लिए आते हैं, लेकिन वहाँ एक clojure.contrib http-एजेंट है जो अपने स्वयं के एजेंट के रूप में प्रत्येक प्राप्त/पोस्ट अनुरोध बनाता है। तो आप हजारों अनुरोधों को बंद कर सकते हैं और वे सभी समानांतर और पूर्ण हो जाएंगे क्योंकि परिणाम आते हैं।

0

pmap के ऑपरेशन को देखते हुए, ऐसा लगता है कि एक समय में 32 धागे नहीं जाते हैं, आप कितने प्रोसेसर नहीं हैं है, मुद्दा यह है कि मानचित्र 32 से गणना के आगे जाएगा और वायदा अपने आप में शुरू हो जाएगा। (नमूना) (defn samplef [n] (println "starting " n) (Thread/sleep 10000) n) (def result (pmap samplef (range 0 100)))

; आप 10 सेकंड तक इंतजार करेंगे और 32 प्रिंट देखेंगे जब आप 33 वें अन्य 32 लेते हैं; इस मिनट को प्रिंट करता है कि आप एक समय में 32 समवर्ती धागे कर रहे हैं ; मेरे लिए यह सही नहीं है ; SALUDOS Felipe