2011-11-21 10 views
5

मैं अपने अनुप्रयोग है कि बहुत काम करता है और सबसे गणना समय पर है में एक बहुत ही सरल कार्य है:स्पीड अप Data.Array पंक्ति निष्कर्षण और छानने

f :: Int -> Array (Int,Int) Int -> [Int] 
f x arr = [v | v <- range (l,u), vv <- [g!(x,v)], vv /= 0] 
      where ((_,l), (_,u)) = bounds arr 

क्या करता है: में एक पंक्ति को निकालने इंडेक्स x सरणी arr से और \= 0 तत्वों के साथ सभी कॉलम इंडेक्स लौटाएं।

arr = [[0, 0, 5], 
     [4, 0, 3], 
     [0, 3, 1]] -- for simplicity in [[a]] notation 

उम्मीद उत्पादन

f 0 arr == [2] 
f 1 arr == [0,2] 
f 2 arr == [1,2] 

है मैं कैसे f में तेजी लाने करते हैं और अधिक विस्तार के साथ प्रोफाइल क्या वास्तव में गणना समय के सबसे लेता है: तो, उदाहरण के लिए, सीमा ((0,0),(2,2)) साथ निम्नलिखित मैट्रिक्स दिया एफ में (सूची निर्माण, सरणी का उपयोग, आदि)?

धन्यवाद! यह arr होना चाहिए

उत्तर

2
f x arr = [v | v <- range (l,u), vv <- [g!(x,v)], vv /= 0] 

मैं g लगता है, कोई गलती है।
range (l,u) के बजाय [l .. u] का उपयोग करें, संकलक पूर्व और बाद वाले को अनुकूलित करने में सक्षम हो सकता है, लेकिन [l .. u] अधिक मूर्खतापूर्ण है (और शायद संकलक पूर्व को अनुकूलित भी नहीं कर सकता है)।
एक व्यर्थ एक तत्व की सूची बनाने के मत करो, आप प्रत्यक्ष परीक्षण का उपयोग कर सकते,

f x arr = [v | v <- [l .. u], arr!(x,v) /= 0] 

संकलक फिर बाद के पूर्व के पुनर्लेखन के लिए सक्षम हो सकता है, लेकिन एक) बाद बहुत स्पष्ट है, और बी) जोखिम नहीं है कि संकलक नहीं कर सकते हैं।

f x arr = [v | v <- {-# SCC "Range" #-} [l .. u], {-# SCC "ZeroTest" #-} (arr!(x,v) /= 0)] 

पता लगाने के लिए जहां समय बिताया है, तो आप लागत केंद्र एनोटेशन सम्मिलित कर सकते हैं, लेकिन इस तरह एनोटेशन कई अनुकूलन (रूपरेखा के लिए हमेशा संकलन करता है) को निष्क्रिय है, तो चित्र आप रूपरेखा से प्राप्त किया जा सकता है अनुकूलित प्रोग्राम में वास्तव में क्या होता है उससे अलग और भिन्न होता है।

http://www.haskell.org/ghc/docs/latest/html/users_guide/profiling.html

और एक किताब अध्याय:

+0

मैंने अभी पुस्तकालयों के स्रोत की जांच की है और 'रेंज'' [..] 'जैसा ही होना चाहिए। – sclv

+0

@ एससीएलवी हां, यह वही है। हालांकि यह एक और परत है जिसे संकलक को छीलना पड़ता है। 'Int' के साथ कोई समस्या नहीं होनी चाहिए, लेकिन अन्य प्रकार के लिए हो सकती है। –

+0

आपकी टिप्पणी के लिए धन्यवाद। इससे वास्तव में काफी मदद मिली और मुझे लगता है कि समस्या सूची का निर्माण है। अंत में मुझे जो चाहिए वह सूची में एक गुना है, इसलिए कॉलर में सीधे सरणी पर गुना करना बेहतर हो सकता है। – bbtrb

2

यहाँ रूपरेखा पर दस्तावेज़ीकरण है

http://book.realworldhaskell.org/read/profiling-and-optimization.html

अपने कोड निकलती है तो, क्योंकि सरणी अद्यतन की धीमी गति से हो vector से Data.Vector.* उपयोग करने के लिए पैकेज।

+0

मैं उन लोगों के साथ-साथ 'डेटा.वेक्टर', पर भी एक नज़र डालेगा। – bbtrb

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