2011-10-03 13 views
9

मुझे यह महसूस हो गया है कि उत्तर हाँ है, और यह हास्केल तक ही सीमित नहीं है। उदाहरण के लिए, पूंछ-कॉल अनुकूलन ओ (एन) से ओ (एल) तक स्मृति आवश्यकताओं को बदलता है, है ना?कंपाइलर ऑप्टिमाइज़ेशन, जैसे ghc -O2, प्रोग्राम के ऑर्डर (टाइम या स्टोरेज) को बदल सकते हैं?

मेरे सटीक चिंता का विषय है: हास्केल संदर्भ में, क्या संकलक अनुकूलन के बारे में समझने के लिए जब प्रदर्शन और एक कार्यक्रम के आकार के बारे तर्क की उम्मीद है?

योजना में, आप कुछ अनुकूलन प्रदान करने के लिए, TCO की तरह लेते हैं, यह देखते हुए कि आप एक दुभाषिया/संकलक कि विनिर्देशों के अनुरूप उपयोग कर रहे हैं कर सकते हैं।

उत्तर

15

हाँ, विशेष रूप से GHC कठोरता विश्लेषण है, जो काफी से हे (एन) अनायास ही आलस्य के साथ एक कार्यक्रम के स्थान उपयोग को कम कर सकतेलिए करता हे (1)

उदाहरण के लिए, इस तुच्छ कार्यक्रम पर विचार करें:

$ cat LazySum.hs 
main = print $ sum [1..100000] 

sum के बाद से स्वीकार नही करता कि इसके अलावा ऑपरेटर सख्त है, (यह एक Num उदाहरण जिसके लिए (+) आलसी है साथ प्रयोग किया जा सकता है), यह कारण होगा आवंटित करने के लिए बड़ी संख्या में थंक्स। अनुकूलन सक्षम किए बिना, कठोरता विश्लेषण नहीं किया जाता है।

$ ghc --make LazySum.hs -rtsopts -fforce-recomp 
[1 of 1] Compiling Main    (LazySum.hs, LazySum.o) 
Linking LazySum ... 
$ ./LazySum +RTS -s 
./LazySum +RTS -s 
5000050000 
     22,047,576 bytes allocated in the heap 
     18,365,440 bytes copied during GC 
     6,348,584 bytes maximum residency (4 sample(s)) 
     3,133,528 bytes maximum slop 
       15 MB total memory in use (0 MB lost due to fragmentation) 

    Generation 0: 23 collections,  0 parallel, 0.04s, 0.03s elapsed 
    Generation 1:  4 collections,  0 parallel, 0.01s, 0.02s elapsed 

    INIT time 0.00s ( 0.00s elapsed) 
    MUT time 0.01s ( 0.03s elapsed) 
    GC time 0.05s ( 0.04s elapsed) 
    EXIT time 0.00s ( 0.00s elapsed) 
    Total time 0.06s ( 0.07s elapsed) 

    %GC time  83.3% (58.0% elapsed) 

    Alloc rate 2,204,757,600 bytes per MUT second 

    Productivity 16.7% of total user, 13.7% of total elapsed 

हालांकि, अगर हम सक्षम अनुकूलन के साथ संकलन, कठोरता विश्लेषक का निर्धारण करेगा कि हम Integer के लिए इसके अलावा ऑपरेटर, जो सख्त होने के लिए जाना जाता है के बाद से उपयोग कर रहे हैं, संकलक जानता है कि यह मूल्यांकन करने के लिए सुरक्षित है समय से पहले thunks, और इसलिए कार्यक्रम निरंतर अंतरिक्ष में चलाता है।

$ ghc --make -O2 LazySum.hs -rtsopts -fforce-recomp 
[1 of 1] Compiling Main    (LazySum.hs, LazySum.o) 
Linking LazySum ... 
$ ./LazySum +RTS -s 
./LazySum +RTS -s 
5000050000 
     9,702,512 bytes allocated in the heap 
      8,112 bytes copied during GC 
      27,792 bytes maximum residency (1 sample(s)) 
      20,320 bytes maximum slop 
       1 MB total memory in use (0 MB lost due to fragmentation) 

    Generation 0: 18 collections,  0 parallel, 0.00s, 0.00s elapsed 
    Generation 1:  1 collections,  0 parallel, 0.00s, 0.00s elapsed 

    INIT time 0.00s ( 0.00s elapsed) 
    MUT time 0.01s ( 0.02s elapsed) 
    GC time 0.00s ( 0.00s elapsed) 
    EXIT time 0.00s ( 0.00s elapsed) 
    Total time 0.01s ( 0.02s elapsed) 

    %GC time  0.0% (2.9% elapsed) 

    Alloc rate 970,251,200 bytes per MUT second 

    Productivity 100.0% of total user, 55.0% of total elapsed 

ध्यान दें कि हम भी अनुकूलन के बिना लगातार अंतरिक्ष प्राप्त कर सकते हैं, हम कड़ाई खुद जोड़ते हैं: हास्केल के मूल्यांकन की वजह से,

$ cat StrictSum.hs 
import Data.List (foldl') 
main = print $ foldl' (+) 0 [1..100000] 
$ ghc --make StrictSum.hs -rtsopts -fforce-recomp 
[1 of 1] Compiling Main    (StrictSum.hs, StrictSum.o) 
Linking StrictSum ... 
$ ./StrictSum +RTS -s 
./StrictSum +RTS -s 
5000050000 
     9,702,664 bytes allocated in the heap 
      8,144 bytes copied during GC 
      27,808 bytes maximum residency (1 sample(s)) 
      20,304 bytes maximum slop 
       1 MB total memory in use (0 MB lost due to fragmentation) 

    Generation 0: 18 collections,  0 parallel, 0.00s, 0.00s elapsed 
    Generation 1:  1 collections,  0 parallel, 0.00s, 0.00s elapsed 

    INIT time 0.00s ( 0.00s elapsed) 
    MUT time 0.00s ( 0.01s elapsed) 
    GC time 0.00s ( 0.00s elapsed) 
    EXIT time 0.00s ( 0.00s elapsed) 
    Total time 0.00s ( 0.01s elapsed) 

    %GC time  0.0% (2.1% elapsed) 

    Alloc rate 9,702,664,000,000 bytes per MUT second 

    Productivity 100.0% of total user, 0.0% of total elapsed 

सख़्ती पूंछ कॉल की तुलना में एक बड़ा मुद्दा है, जो aren't really a useful concept in Haskell हो जाता है आदर्श।

+0

क्या पूंछ कॉल के बारे में हास्केल मानक गारंटी करता है? –

+0

@DanielWagner: ठीक है, वे वास्तव में सीधे उल्लेख नहीं किया जाता है, क्योंकि यह वास्तव में हास्केल के मूल्यांकन मॉडल पर लागू नहीं होता है। मुझे इस समय एक अच्छा संदर्भ नहीं मिल रहा है, लेकिन मुझे पूरा यकीन है कि यह गारंटी है कि 'फ़ोल्ड' (+) 0 [1..100000] 'जैसे कुछ स्थिर स्थान पर चलता है। – hammar

+0

यह 'फोल्ड' होना चाहिए (+) 0 [1..एन] '। इनपुट का आकार निश्चित होने पर सबकुछ स्थिर होता है :) – hammar

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