我試圖做一個功能更有效,但我已最差,我不明白爲什麼。有人能看出原因並向我解釋嗎?需要幫助分析代碼和分析結果
原來的功能:
substringsSB s = substringsSB' Set.empty s
substringsSB' m s = substrings' m s
where
substrings' m s = {-# SCC "substrings'" #-}if (Set.member s m) then m else foldl' insertInits m (init . B.tails $ s)
insertInits m s = {-# SCC "insertInits" #-}if (Set.member s m) then m else foldl' doInsert m (tail . B.inits $ s)
doInsert m k = {-# SCC "doInsert" #-}Set.insert k m
剖析結果:
total time = 3.14 secs (157 ticks @ 20 ms)
total alloc = 1,642,067,360 bytes (excludes profiling overheads)
COST CENTRE MODULE %time %alloc
doInsert Main 95.5 92.1
insertInits Main 2.5 7.8
substringsSB' Main 1.9 0.0
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
MAIN MAIN 1 0 0.0 0.0 100.0 100.0
main Main 280 1 0.0 0.0 100.0 100.0
substringsSB Main 281 1 0.0 0.0 100.0 100.0
substringsSB' Main 282 1 1.9 0.0 100.0 100.0
doInsert Main 285 1233232 95.5 92.1 95.5 92.1
insertInits Main 284 1570 2.5 7.8 2.5 7.8
substrings' Main 283 1 0.0 0.0 0.0 0.0
CAF GHC.IO.Handle.FD 211 3 0.0 0.0 0.0 0.0
CAF GHC.IO.Encoding.Iconv 169 2 0.0 0.0 0.0 0.0
CAF GHC.Conc.Signal 166 1 0.0 0.0 0.0 0.0
據我所知,我們不能有早期的出口在
倍
foldl
,因此函數可以花很多時候只是打電話Set.member s m
和substrings'
返回m
。所以,我轉換的功能,使用遞歸:
substringsSB s = substringsSB' Set.empty s
substringsSB' m str = substrings' m (init . B.tails $ str)
where
substrings' m [] = m
substrings' m (s:ss) | Set.member s m = m
| otherwise = {-# SCC "substrings'" #-}substrings' insertTail ss
where insertTail = insertInits m $ reverse $ (tail . B.inits $ s)
insertInits m [] = m
insertInits m (s:ss) | Set.member s m = m
| otherwise = {-# SCC "insertInits" #-}insertInits (doInsert s m) ss
doInsert k m = {-# SCC "doInsert" #-}Set.insert k m
剖析結果:
total time = 5.16 secs (258 ticks @ 20 ms)
total alloc = 1,662,535,200 bytes (excludes profiling overheads)
COST CENTRE MODULE %time %alloc
doInsert Main 54.7 90.5
substringsSB' Main 43.8 9.5
insertInits Main 1.6 0.0
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
MAIN MAIN 1 0 0.0 0.0 100.0 100.0
main Main 280 1 0.0 0.0 100.0 100.0
substringsSB Main 281 1 0.0 0.0 100.0 100.0
substringsSB' Main 282 1 43.8 9.5 100.0 100.0
doInsert Main 285 1225600 54.7 90.5 54.7 90.5
insertInits Main 284 1225600 1.6 0.0 1.6 0.0
substrings' Main 283 1568 0.0 0.0 0.0 0.0
CAF GHC.IO.Handle.FD 211 3 0.0 0.0 0.0 0.0
CAF GHC.IO.Encoding.Iconv 169 2 0.0 0.0 0.0 0.0
CAF GHC.Conc.Signal 166 1 0.0 0.0 0.0 0.0
但是這需要更多的時間比原來的版本。 爲什麼花了這麼多時間在substringsSB'
? 它只是做init . B.tails $ str
其原始版本也呼籲... 還是我犯了一個錯誤,並且這兩個功能都沒有邏輯上等同?
main = do
s <- getLine
let m = substringsSB $ B.pack s
print $ Set.size m
return()
與輸入:
asjasdfkjasdfjkasdjlflaasdfjklajsdflkjasvdadufhsaodifkljaiduhfjknhdfasjlkdfndbhfisjglkasnjjfgklsadmsjnhsjdflkmsnajjkdlsmfnjsdkfljasd;fjlkasdjfklasjdfnasdfjjnsadfjsadfhasjdfjlaksdfjlkasdfjljkasdflasidfjlaisjdflaisdjflaisjdfliasjdgfouqhagdfsia;klsjdfnklajsdfkhkasfhjdasdfhaskdflhjaklsdfh;kjlasdfh;jlaksdflkhajsdfkjahsdfkjhasdfkkasdfkjlkasfdkljasdfkhljkasdkflkjasdfasdlfkajsdlfkjaslkdfjjaksdjgujhgjhghjbjnbghjghhgfghfghvfgfgjhgjhdfjfjhgfjgvjhgvjhgvjhgvjhgvjhgvjhasdkfjkasdjfklajsdfklkahsdfjklhjklhghjhkhgfvcghjkjhghjkjhhvjkl/ljklkjlkjlkjlkjaslkdfjasd;lkfjas;dlfkjas;dflkjas;dflkjas;dflkjas;dflkja;slkdfja;sdlkjfa;sdlkfja;lsdfkjas;ldkfja;sdlkfja;skldfja;slkdjfa;slkdfja;sdklfjas;dlkfjas;dklfjas;dlkfjas;dfkljas;dflkjas;lkdfja;sldkfj;aslkdfja;sldkfja;slkdfj;alksdjf;alsdkfj;alsdkfja;sdflkja;sdflkja;sdlfkja;sdlfkja;sldkfja;sdlkfja;sldfkj;asldkfja;sldkfja;lsdkfja;sldfkja;sdlfjka;sdlfjkas;dlkfjas;ldkfjas;dlfkjasfd;lkjasd;fljkads;flkjasdf;lkjasdf;lkajsdf;lkajsdf;aksljdf;alksjdfa;slkdjfa;slkdjfa;slkdfja;sdflkjas;dflkjasd;flkjasd;flkjasdf;lkjasdf;ljkasdf;lkajdsf;laksjf;asldfkja;sdfljkads;flkjasd;fljkasdf;lkjasdf;ljkadfs;fljkadfs;ljkasdf;lajksdf;lkajsdf;lajsfd;laksdfgvjhgvjhgvjhcfjhgcjfgvjkgvjjgfjghfhgkhkjhbkjhbkjhbkybkkugtkydfktyufctkyckxckghfvkuygjkhbykutgtvkyckjhbliuhgktuyfkvuyjbjkjygvkuykjdjflaksdjflkajsdlkfjalskdjflkasjdflkjasdlkfjalksdjfklajsdflkjasdlkjfalksdjflkasjdflkjasdlfkjaslkdjflaksjdflkajsdlfkjasdlkfjalsdjflkasjdflkasjdflajsdfjsfuhaduvasdyhaweuisfnaysdfiuhasfdnhaksjdfahsdfiujknsadfhbaiuhdfjknahbdshfjksnashdfkjnsadfiukjfnhsdfkjnasdfikjansdfhnaksdjfaisdfkn
請注意,只要不強制第二個參數,您就可以「提早退出」懶惰的摺疊器。 – ehird 2012-01-08 05:59:18
當我用一箇中等大小的字符串測試它們時,我看到兩個函數之間有不同的結果:https://gist.github.com/75d265248de0e0546174 – 2012-01-08 07:33:41
@ehird:是的,我打算說'foldl',我會看一看我是否可以在我的情況下使用'foldr'。 – ePak 2012-01-08 09:14:53