我试图做一个功能更有效,但我已最差,我不明白为什么。有人能看出原因并向我解释吗?需要帮助分析代码和分析结果
原来的功能:
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