containers icon indicating copy to clipboard operation
containers copied to clipboard

An alternative version of `levels` for `Data.Tree`

Open xgrommx opened this issue 3 years ago • 4 comments

Hello everyone, how about an alternative version levels for Data.Tree?

levels :: Tree a -> [[a]]
levels t = unfoldr go [t] where
  go [] = Nothing
  go xs = Just . foldMap (\x -> ([rootLabel x], subForest x)) $ xs

xgrommx avatar Jan 31 '21 11:01 xgrommx

seems slower and needs more space than the current implementation (extra allocations for Maybe and Pair)

crude way of measuring, in ghci

import Data.Tree
bin n = Node () $ map bin [0..n-1]
t = bin 18

:set +s

length $ concat $ levels  t   -- from Data.Tree
262144
(0.15 secs, 58,787,192 bytes)

length $ concat $ lvls  t   -- your proposal
262144
(0.94 secs, 136,944,168 bytes)

do you have other data? Perhaps ghc's inliner can remove extra allocations - but that needs proof.

jwaldmann avatar Jan 31 '21 18:01 jwaldmann

@jwaldmann Ok, I have another variant

levels :: Tree a -> [[a]]
levels t = unfoldr go [t] where
  go [] = Nothing
  go xs = Just (fmap rootLabel xs, xs >>= subForest)

xgrommx avatar Jan 31 '21 18:01 xgrommx

measure it.

jwaldmann avatar Jan 31 '21 18:01 jwaldmann

@jwaldmann

*Main> length $ concat $ levels t
262144
(0.03 secs, 61,413,320 bytes)
*Main> length $ concat $ T.levels t
262144
(0.03 secs, 59,313,488 bytes)

xgrommx avatar Jan 31 '21 18:01 xgrommx