packages feed

typed-streams-0.1.0.0: test/Tests.hs

module Main (main) where

import qualified Data.Generic.Enum as E
import Data.Stream.Typed (RunTimeStream)
import Data.Semigroup (Semigroup((<>)))

import Data.Bits ((.&.))
import Data.Foldable (foldl')

import Criterion

n :: Int
n = 10000000

f :: Int -> Int
f x = x*(x .&. 3)

g :: Int -> Int
g x = x*(x .&. 7)

xs :: Int -> RunTimeStream Int
xs n = E.enumFromTo 1 n

xl :: Int -> [Int]
xl n = [1..n]

sumG :: (Functor t, Foldable t, Semigroup (t Int)) => t Int -> Int
sumG x = foldl' (+) 0 ((fmap f x) <> (fmap g x))

sumS n = sumG (xs n)
sumL n = sumG (xl n)

fast :: Int -> Int
fast n = go g (go f 0 1 n) 1 n where
  go :: (Int -> Int) -> Int -> Int -> Int -> Int
  go f = go' where
    go' :: Int -> Int -> Int -> Int
    go' acc s i = if i == 0 then acc else let next_acc = acc + f s in next_acc `seq` go' next_acc (s + 1) (i - 1)

main :: IO ()
main = do
  putStrLn ("n = " ++ show n)
  putStrLn $ "Hand coded strict loop (Result = " ++ show (fast n) ++ " ):"
  benchmark (nf fast n)
  putStrLn $ "Using lists (Result = " ++ show (sumL n) ++ " ):"
  benchmark (nf sumL n)
  putStrLn $ "Using streams (Result = " ++ show (sumS n) ++ " ):"
  benchmark (nf sumS n)