私は機能をより効率的にしようとしていますが、私はそれを最悪にしました。誰かがなぜそれを見て、私に説明してもらえますか?コードとプロファイリングの結果を分析する際に助けが必要です
オリジナル機能:
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
に早期の出口を持つことができませんので、機能を過ごすことができます
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
結果をプロファイリング多くの時間はSet.member s m
となり、m
はsubstrings'
に戻ります。
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'
に費やしていますか? また、私は間違いを犯しましたが、これらの2つの機能は論理的に同等ではありませんか? 入力と
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
2番目の引数を強制しないことによって、レイジー折りたたみを「早期に終了」することができます。 – ehird
中規模の文字列でテストすると、2つの関数の間で異なる結果が表示されます。https://gist.github.com/75d265248de0e0546174 –
@ehird:はい、私は 'foldl'と言うつもりです私が実際に私の場合に 'foldr'を使うことができるかどうか。 – ePak