2011-09-22 11 views
7

यह एक आम ज्ञान है कि कोई Haskell में बड़ी मात्रा में डेटा पढ़ने के लिए [Char] का उपयोग नहीं करता है। नौकरी करने के लिए ByteString एस का उपयोग करता है। इसके लिए सामान्य स्पष्टीकरण यह है कि Char एस बड़े हैं और सूचियां उनके ऊपरी हिस्से को जोड़ती हैं।हास्केल में [चार] आधारित आउटपुट की तुलना में [चार] आधारित इनपुट इतना धीमा क्यों है?

हालांकि, यह आउटपुट के साथ कोई समस्या नहीं प्रतीत होता है।

उदाहरण के लिए निम्नलिखित कार्यक्रम:

import Data.List 

sum' :: [Int] -> Int 
sum' = foldl' (+) 0 

main = interact $ show . sum' . map read . words 

3,38 सेकंड लेता है, तो पहला कार्यक्रम के उत्पादन में खिलाया:

main = interact $ const $ unwords $ map show $ replicate 500000 38000000 

जबकि निम्न में से एक, अपने कंप्यूटर पर चलाने के लिए सिर्फ 131 एमएस लेता है एक इनपुट के रूप में!

String एस का उपयोग करके इनपुट और आउटपुट प्रदर्शन के बीच ऐसी असमानता का कारण क्या है?

+1

मेरी त्वरित प्रोफाइलिंग से पता चलता है कि इनपुट प्रोग्राम आउटपुट प्रोग्राम की तुलना में 13 गुना अधिक स्मृति आवंटित करता है। यह निश्चित रूप से असमानता में योगदान देता है। –

उत्तर

10

मुझे नहीं लगता कि इस मुद्दे को आई/ओ के साथ जरूरी है। इसके बजाय, यह दर्शाता है कि ReadInt के लिए उदाहरण बहुत अक्षम है।

सबसे पहले, निम्न प्रोग्राम पर विचार करें जो केवल आलसी सूची को संसाधित करता है।

main = print $ sum' $ map read $ words 
     $ unwords $ map show $ replicate 500000 38000000 

length साथ read समारोह की जगह 0.48s करने के लिए नीचे समय चला जाता है:: यह मेरी मशीन (-O2 साथ संकलित) पर 4.1s लेता

main = print $ sum' $ map length $ words 
     $ unwords $ map show $ replicate 500000 38000000 

इसके अलावा, एक हस्तलिखित साथ read समारोह की जगह 0.52s का एक समय में संस्करण परिणाम:

main = print $ sum' $ map myread $ words 
     $ unwords $ map show $ replicate 500000 38000000 

myread :: String -> Int 
myread = loop 0 
    where 
    loop n [] = n 
    loop n (d:ds) = let d' = fromEnum d - fromEnum '0' :: Int 
         n' = 10 * n + d' 
        in loop n' ds 

मेरे क्यों read के रूप में अनुमान मैं यह इतना अक्षम है कि इसका कार्यान्वयन Text.ParserCombinators.ReadP मॉड्यूल का उपयोग करता है, जो एकल पूर्णांक पढ़ने के साधारण मामले के लिए सबसे तेज़ विकल्प नहीं हो सकता है।

+1

ओह, इसलिए 'स्ट्रिंग' का उपयोग न करने का मुख्य कारण 'स्ट्रिंग' के साथ कुछ भी नहीं है। यह बहुत अनुचित है। – Rotsor

+2

निष्पक्ष होने के लिए, 'रीड' कुछ चीजें करता है जो 'myread' नहीं करता है: त्रुटि जांच, व्हाइटस्पेस छोड़ना, ऋणात्मक संख्या, हेक्साडेसिमल, ऑक्टल, और यहां तक ​​कि (आश्चर्य!) घातीय नोटेशन। –

+0

एक 'पढ़ने' के लिए ऑक्टेट्स कैसे लिखता है? मुझे उम्मीद है कि यह '0' के साथ एक संख्या उपसर्ग नहीं है। – Rotsor

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