2015-09-21 7 views
9

निरंतर स्थान में एक monadic कार्रवाई का उपयोग करके मैं आलसी सूची कैसे जोड़ सकता हूं? जिस समस्या को मैं हल करने की कोशिश कर रहा हूं वह एक बड़ी फाइल को जोड़ रहा है, और मुझे विश्वास के लिए विश्वास है कि मुझे उत्परिवर्तन की आवश्यकता है। मेरे पास म्यूटेबल वैक्टर का उपयोग करके एसटी में काम करने का कार्यान्वयन है, लेकिन यह बहुत अधिक स्मृति का उपयोग करता है। नीचे मैं जो कोशिश कर रहा हूं उसका एक उदाहरण है। मैंने कंडिट के साथ संक्षेप में भी प्रयोग किया लेकिन यह कोई सुधार प्रदान नहीं करता था।कॉन्सटेंट स्पेस में मोनाडिक फोल्ड

अनुसूचित जनजाति forM_:

import Control.Monad (forM_) 
import Control.Monad.ST.Trans as STT 
import Control.Monad.Identity as Identity 

testST :: Int 
testST = do 
    Identity.runIdentity $ STT.runST $ do 
    a <- STT.newSTRef 0 
    forM_ [1..10000000] (\x -> do 
     a' <- STT.readSTRef a 
     STT.writeSTRef a (a' + x) 
    ) 
    STT.readSTRef a 

नाली:

import Data.Conduit (($=),(=$),($$)) 
import qualified Data.Conduit as C 
import qualified Data.Conduit.List as CL 

testCL :: IO Int 
testCL = CL.sourceList [1..10000000] $$ CL.foldM (\a x -> return (a + x)) 0 
+0

प्रदर्शन ट्यूनिंग के लिए: ऐसा लगता है कि 'एसटीटी एस पहचान' के सामान्य 'एसटी एस' पर कुछ आवंटन ओवरहेड होगा; अगर आपको असाधारण 'एसटीटी' शक्तियों की आवश्यकता नहीं है, तो आप केवल 'एसटी' का उपयोग करना चाहेंगे। – dfeuer

+0

@dfeuer वास्तव में मैं इसे हटा सकता हूं, लेकिन मैंने इसे लागू करने के लिए शुरू में 'या तो' एम्बेड करने की आवश्यकता होने की उम्मीद की और इसे स्थानांतरित कर दिया गया। पारितोषिक के लिए धन्यवाद! – ryachza

उत्तर

15

समस्या गुना के साथ नहीं है, लेकिन गुना शरीर के साथ। इस कार्यक्रम के एक बहुत आवंटित:

testST = runST $ do 
    ref <- newSTRef 0 
    forM_ [1..10000000] $ \x -> do 
     val <- readSTRef ref 
     writeSTRef ref $! val + x 
    readSTRef ref 

कोड के दो टुकड़े के बीच अंतर क्या करने के लिए एक अच्छा संकेत है:

testST = runST $ do 
    ref <- newSTRef 0 
    forM_ [1..10000000] $ \x -> do 
     val <- readSTRef ref 
     writeSTRef ref (val + x) 
    readSTRef ref 

इस कार्यक्रम है, जिसका फर्क सिर्फ इतना है writeSTRef लाइन पर है, लगभग कुछ भी नहीं आवंटित आगे बढ़ रहा है: पूर्व में, आप + के अनुप्रयोगों की 10000000 परतों के साथ गहराई से घोंसला वाले थंक का संदर्भ बना रहे हैं; जबकि उत्तरार्द्ध प्रत्येक चरण में थंक flattens।

वैसे, यह आम pitfall explicitly called out in the documentation for modifySTRef है।

+0

धन्यवाद यह पूरी तरह से काम किया। मैंने कई कठोरता एनोटेशन और विभिन्न फ़ोल्ड विधियों की कोशिश की लेकिन मेरा ध्यान हमेशा तर्कों पर था कि एप्लिकेशन नहीं। सोचा था कि यह लिखने का मूल्य कभी भी मेरे दिमाग को पार नहीं कर पाया। – ryachza

+0

@ryachza वास्तव में, यह एक सूक्ष्म त्रुटि है, जो कि देर रात की निराशा से मेरे दिमाग में जला दिया गया था, आखिरी मिनट डीबगिंग सत्र ... –

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