packages feed

packed-data-0.2.0.0: benchmark/tree/List.hs

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TemplateHaskell #-}

module List (benchmark) where

import Control.DeepSeq
import Criterion.Main
import Data.Packed
import qualified Data.Packed.Reader as R
import Foreign
import Prelude hiding (sum)

data Tree1 a = Leaf1 | Node1 (Tree1 a) a (Tree1 a)

instance NFData (Tree1 a) where
    rnf Leaf1 = ()
    rnf (Node1 l n r) = n `seq` l `seq` r `seq` ()

$(mkPacked ''Tree1 [InsertFieldSize])

benchmark :: [Int] -> Benchmark
benchmark _ =
    bgroup
        "list"
        []

-- bgroup
--     "from-list"
--     $ fmap buildTreeFromListWithLength depths
-- , bgroup
--     "to-list"
--     $ fmap treeToListWithLength depths

-- buildTreeFromListWithLength :: Int -> Benchmark
-- buildTreeFromListWithLength n =
--     bgroup
--         (depthGroupName n)
--         [ bench nativeTestName $ nf buildTreeFromList list
--         , bench packedTestName $ nfAppIO buildPackedTreeFromList list
--         ]
--   where
--     list = buildUnorderedList n

-- treeToListWithLength :: Int -> Benchmark
-- treeToListWithLength n =
--     bgroup
--         (depthGroupName n)
--         [ bench nativeTestName $ nf treeToList (buildTreeFromList list)
--         , env (buildPackedTreeFromList list) $
--             bench packedTestName
--                 . nfAppIO
--                     (runReader packedTreeToList)
--         ]
-- where
--   list = buildUnorderedList n

buildTreeFromList :: [Int] -> Tree1 Int
buildTreeFromList = foldl (flip insertInTree) Leaf1
  where
    insertInTree n Leaf1 = Node1 Leaf1 n Leaf1
    insertInTree n (Node1 l n' r) =
        if n > n'
            then Node1 l n' (insertInTree n r)
            else Node1 (insertInTree n l) n' r

treeToList :: Tree1 Int -> [Int]
treeToList t = go t []
  where
    go Leaf1 r = r
    go (Node1 l n r) list = go l (n : go r list)

packedTreeToList :: PackedReader '[Tree1 Int] '[] [Int]
packedTreeToList = go []
  where
    go :: [Int] -> PackedReader '[Tree1 Int] r [Int]
    go l =
        caseTree1
            (R.return l)
            ( R.do
                packedLeft <- isolate
                n <- readerWithFieldSize
                packedRight <- isolate
                rightList <- R.lift (go l) packedRight
                R.lift (go $ n : rightList) packedLeft
            )

--
-- buildPackedTreeFromList :: [Int] -> IO (Packed '[Tree1 Int])
-- buildPackedTreeFromList l =
--     finish
--         =<< withEmptyNeeds
--         =<< foldl
--             ( \builder i -> R.do
--                 n <- insertInPackedTree i
--                 R.return (builder N.>> n)
--             )
--             (write Leaf1)
--             l
--   where
--     packedToNeeds :: Packed a -> Needs '[] a
--     packedToNeeds p = let (BS.BS fptr l) = fromPacked p in Needs fptr l l
--     insertInPackedTree ::
--         Int ->
--         PackedReader '[Tree1 Int] '[] (N.NeedsBuilder '[] '[Tree1 Int] '[] '[Tree1 Int])
--     insertInPackedTree n =
--         caseTree1
--             ( mkPackedReader
--                 ( \p l -> do
--                     let n =
--                             ( N.do
--                                 startNode1
--                                 writeWithFieldSize Leaf1
--                                 writeWithFieldSize 0
--                                 writeWithFieldSize Leaf1
--                             )
--                     return (n, p, l)
--                 )
--             )
--             ( R.do
--                 !left <- isolate
--                 !n' <- readerWithFieldSize
--                 !right <- isolate
--                 let !needLeft = packedToNeeds left
--                 let !needRight = packedToNeeds right
--                 needsN' <- mkPackedReader (\p l -> (,p,l) <$> withEmptyNeeds (write n'))
--                 if n > n'
--                     then R.do
--                         right' <- R.lift (insertInPackedTree n) right
--                         R.return (repackNode1 needLeft needsN' right')
--                     else R.do
--                         left' <- R.lift (insertInPackedTree n) left
--                         R.return (repackNode1 left' needsN' needRight)
--             )
--
buildUnorderedList :: Int -> [Int]
buildUnorderedList n = intercalate [(n `div` 2) .. n] [0 .. (n `div` 2) - 1]
  where
    intercalate a [] = a
    intercalate [] b = b
    intercalate (a : b) (c : d) = a : c : intercalate b d