2013-05-14 2 views
8

के प्रदर्शन में सुधार करें मेरे पास क्लोजरस्क्रिप्ट प्रोग्राम है जो मुख्य रूप से संग्रह पर गणित की गणना करता है। यह मूर्खतापूर्ण, मेजबान-स्वतंत्र क्लोजर में विकसित किया गया था, इसलिए इसे बेंचमार्क करना आसान है। मेरे आश्चर्य के लिए (और उत्तर Which is faster, Clojure or ClojureScript (and why)? पर दिए गए उत्तरों के विपरीत), क्लोजरस्क्रिप्ट में एक ही कोड क्लोजर समकक्ष की तुलना में 5-10 गुना धीमा चलता है।क्लोजरस्क्रिप्ट प्रोग्राम

यहां मैंने जो किया है। मैंने lein repl खोला और एक ब्राउज़र http://clojurescript.net/ पर प्रतिलिपि बना दिया। तब मैंने इन स्निपेट दोनों आरईपीएल में कोशिश की।

(time (dotimes [x 1000000] (+ 2 8))) 

(let [coll (list 1 2 3)] (time (dotimes [x 1000000] (first coll)))) 

तब मैं ब्राउज़र repl पर एक JavaScript कंसोल खोला और एक minimalist बेंचमार्क समारोह,

function benchmark(count, fun) { 
    var t0 = new Date(); 
    for (i = 0; i < count; i++) { 
    fun(); 
    } 
    var t1 = new Date(); 
    return t1.getTime() - t0.getTime(); 
} 

ब्राउज़र पर वापस आरईपीएल लिखा है:

(defn multiply [] (* 42 1.2)) 

फिर दोनों देशी जावास्क्रिप्ट कोशिश गुणा, और जावास्क्रिप्ट कंसोल में इसके क्लोजरस्क्रिप्ट संस्करण,

benchmark(1000000, cljs.user.multiply); 

benchmark(1000000, function(){ 42 * 1.2 }); 

मैं

  • मूल निवासी जावास्क्रिप्ट गणित क्या पाया clojure में गणित के बराबर है
  • ClojureScript उनमें से या तो से 5-10 गुना धीमी

अब मेरे सवाल, कैसे है क्या मैं अपने क्लोजरस्क्रिप्ट प्रोग्राम के प्रदर्शन में सुधार कर सकता हूं?

कुछ दृष्टिकोण वापस परिवर्तनशील जावास्क्रिप्ट सरणियों और परदे के पीछे वस्तुओं का उपयोग करने के मैं अब तक

  • पतन पर विचार किया है रहे हैं। (क्या यह संभव है?)
  • मूल जावास्क्रिप्ट गणित ऑपरेटरों का उपयोग करने के लिए वापस गिरें। (सब पर यह संभव है?)
  • उपयोग जावास्क्रिप्ट सरणियों स्पष्ट (aget js/v 0)
  • clojure के लिए जावास्क्रिप्ट की एक कम महत्वाकांक्षी क्रियान्वयन का उपयोग के साथ, https://github.com/chlorinejs/chlorine या https://github.com/gozala/wisp की तरह वे एक अधिक मुहावरेदार जावास्क्रिप्ट उत्पन्न है, लेकिन वे नामस्थान का समर्थन नहीं करते जो मैं बहुत उपयोग कर रहा हूँ।

उत्तर

10

जावास्क्रिप्ट स्पष्ट वापसी तो

function() { 42 * 1.2 } 

कुछ नहीं करता है,; आप

function() { return 42 * 1.2 } 

इसके बजाय बेंचमार्क करना चाहते हैं। यह क्लोजरस्क्रिप्ट संस्करण का संकलन करने के लिए बिल्कुल वैसा ही होता है, इसलिए कोई अंतर नहीं होगा (क्लोजरस्क्रिप्ट में, गैर-उच्च-क्रम उपयोग में मूल अंकगणितीय फ़ंक्शंस नियमित ऑपरेटर-आधारित जावास्क्रिप्ट अभिव्यक्ति के रूप में उल्लिखित होते हैं)।

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

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

(def arr (long-array 1)) 

;;; benchmark this 
(dotimes [_ 1000000] 
    (aset (longs arr) 0 (inc (aget (longs arr) 0)))) 

बेंचमार्क कुछ करने के लिए बेहतर (longs कॉल Clojure में प्रतिबिंब से बचने के लिए, यह भी ^longs संकेत इस्तेमाल कर सकते हैं)।

आखिरकार, क्लोजर और क्लोजरस्क्रिप्ट दोनों में यह निश्चित रूप से मामला है, कि विशेष रूप से प्रदर्शन-संवेदनशील कोड के कुछ प्रकार के लिए देशी सरणी और इस तरह का उपयोग करना सबसे अच्छा है। सौभाग्य से, वहाँ ऐसा करने के साथ कोई समस्या नहीं है: ClojureScript पक्ष पर, आप array, js-obj, aget, aset, make-array मिल गया है, तो आप :mutable मेटाडाटा खेतों पर deftype में set! करने के लिए उन्हें विधि निकायों आदि में उपयोग कर सकते हैं सक्षम होने के लिए

7

क्लोजरस्क्रिप्ट गणित जावास्क्रिप्ट गणित है। हां, यदि प्रदर्शन महत्वपूर्ण है, तो जावास्क्रिप्ट सरणी और प्रदत्त निम्न-स्तरीय ऑपरेटरों का उपयोग करें, इन्हें जहां संभव हो इष्टतम कोड बनाने की गारंटी दी जाती है (यानी कोई उच्च आदेश उपयोग नहीं)। ClojureScript लगातार डेटा संरचनाओं को इस तरह लिखा गया है: सरणी उत्परिवर्तन, अंकगणित, थोड़ा twiddling।

मेरे पास कुशल क्लोजरस्क्रिप्ट - http://github.com/swannodette/cljs-stl/blob/master/src/cljs_stl/spectral/demo.cljs का एक छोटा सा उदाहरण है जो आपको एक गाइड के रूप में उपयोगी हो सकता है।

+1

मैंने सोचा था कि क्लोजरस्क्रिप्ट में कहीं स्पेक्ट्रल मानक था! उस पर +1। –

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