2014-04-04 8 views
5

मैं 1 + 1/2 + 1/3 + ... + 1/100000000 (डबल फ्लोट का उपयोग करके) की गणना करना चाहता हूं।रैकेट कोड के इस टुकड़े को अनुकूलित कैसे करें?

SBCL साथ

, इस कोड सी में के रूप में के रूप में तेजी से चलाता है:

(loop for i fixnum from 1 to 100000000 sum (/ 1.0d0 i) double-float) 

मैं Typed रैकेट में इस कोड को कैसे अनुकूलित कर सकते हैं? मैं कोशिश की है

#lang typed/racket 

(define: (test) : Float 
     (for/fold: : Float 
        ([s : Float 0.0]) 
        ([i : Fixnum (in-range 1 100000001)]) 
        (+ s (/ 1.0 i)))) 

(time (test)) 

इस कोड को केवल एक सा untyped एक की तुलना में तेजी है। क्या मैं आगे जा सकता हूँ?

+4

एक त्वरित सुझाव है ['अनुकूलन-कोच' पैकेज] (https://github.com/stamourv/optimization-coach/tree/master) को आजमाएं। –

उत्तर

7

यदि आप ग्रेग की तरह इस पर ऑप्टिमाइज़ेशन कोच चलाते हैं, तो यह तुरंत आपको बताता है कि लूप बॉडी धीमा है क्योंकि / फ़ंक्शन मिश्रित अंकगणित (फिक्सनम और फ्लोनम पर) कर रहा है। यदि आप i के स्थान पर (fx->fl i) डालते हैं तो यह तेज़ है (मेरी मशीन पर 2x के करीब)।

इसके अलावा, यदि आप DrRacket में यह समय दे रहे हैं तो आप इसके बजाय racket निष्पादन योग्य के साथ समय बिताना चाहेंगे। DrRacket डिबगिंग उपकरण जोड़ता है जो विकास के दौरान मदद करता है, लेकिन समय के लिए अच्छा नहीं है।

+4

'fx-> fl' के बजाय 'सटीक-> अचूक' या 'असुरक्षित-एफएक्स-> fl' का उपयोग करके ~ 30% गति प्रदान करता है क्योंकि यह जांच करता है कि तर्क वास्तव में एक फ़िक्सम है। – stchang

+4

इसके अलावा, कुछ प्रारंभिक बेंचमार्किंग इंगित करता है कि इस कार्यक्रम के लिए अनुकूलित टाइप किए गए रैकेट कोड एसबीसीएल की तुलना में ~ 10% तेज है। – stchang

2

यहां एक नया संस्करण है, जिसमें मैंने फ्लोट को संक्षेप में थोड़ा सा सहायक मैक्रो बनाया है।

#lang typed/racket 

(require syntax/parse/define) 

(define-simple-macro (for/flsum x ... (c ...) b ... e) 
    (for/fold : Float x ... ([s 0.0]) (c ...) b ... (+ s e))) 

(time (for/flsum ([i : Positive-Fixnum (in-range 1 100000001)]) (/ 1.0 i))) 

ध्यान दें कि Positive-Fixnum का उपयोग कर के रूप में प्रकार का मतलब है कि हम किसी भी अतिरिक्त रूपांतरण की जरूरत नहीं है - Typed रैकेट जानता है कि i 0 कभी नहीं है, और इसलिए / हमेशा अनुकूलित किया जा सकता है। यह अब मेरी मशीन पर लगभग एसबीसीएल जितना तेज़ चलता है। यह एक अपवाद को जन्म देती है, जबकि रैकेट में +inf.0 पैदा करता है -

यह और SBCL कोड के बीच फर्क सिर्फ इतना है कि fixnum सकारात्मक है, की आवश्यकता होती है जो क्योंकि SBCL (/ 1.0 0) और (/ 1.0 0.0) के लिए एक ही अर्थ विज्ञान है निर्दिष्ट करने के लिए की जरूरत है दूसरा मामला और पहले मामले में एक अपवाद।

मैं for/flsum या रैकेट को अपने जैसा कुछ जोड़ने की योजना बना रहा हूं।

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