module Main where

import Control.DeepSeq
import Data.Monoid

import Criterion.Types
import Progression.Config
import Progression.Main

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL

import qualified Data.Binary.Builder as Binary

instance NFData B.ByteString

instance NFData BL.ByteString where
	rnf a = rnf (BL.toChunks a)

bytes_100 :: B.ByteString
bytes_100 = B.replicate 100 0x61

build_strict :: Int -> B.ByteString
build_strict n = BL.toStrict (Binary.toLazyByteString builder) where
	chunks = replicate n (Binary.fromByteString bytes_100)
	builder = foldr Binary.append Binary.empty chunks

build_lazy :: Int -> BL.ByteString
build_lazy n = Binary.toLazyByteString builder where
	chunks = replicate n (Binary.fromByteString bytes_100)
	builder = foldr Binary.append Binary.empty chunks

build_strict_mconcat :: Int -> B.ByteString
build_strict_mconcat n = BL.toStrict (Binary.toLazyByteString builder) where
	chunks = replicate n (Binary.fromByteString bytes_100)
	builder = mconcat chunks

build_lazy_mconcat :: Int -> BL.ByteString
build_lazy_mconcat n = Binary.toLazyByteString builder where
	chunks = replicate n (Binary.fromByteString bytes_100)
	builder = mconcat chunks

benchmarks :: [Benchmark]
benchmarks =
	[ bench "strict" (nf build_strict 1000)
	, bench "strict +mconcat" (nf build_strict_mconcat 1000)
	, bench "lazy" (nf build_lazy 1000)
	, bench "lazy +mconcat" (nf build_lazy_mconcat 1000)
	]

main :: IO ()
main = defaultMainWith config (bgroup "all" benchmarks)

config = Config
	{ cfgMode = Nothing
	, cfgRun = RunSettings [] (Just "01_binary")
	, cfgGraph = mempty
	}
