{-# LANGUAGE TemplateHaskell #-}
module Main where
import Criterion.Main
import Data.Text.Glyphize
import Data.FileEmbed
import System.FilePath ((</>))
import qualified Data.Text.Foreign as Txt
import qualified Data.Text.Lazy as Txt
import Control.Parallel.Strategies (parMap, rdeepseq)
import Data.Word (Word8)
-- Benchmarking these as well...
import Foreign.Marshal.Array (peekArray)
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtrArray)
import System.IO.Unsafe (unsafePerformIO, unsafeDupablePerformIO, unsafeInterleaveIO)
import Data.Text.Glyphize.Array
shapeStr txt = shape font defaultBuffer { text = txt } []
where font = createFont $ createFace $(
makeRelativeToProject ("assets" </> "Lora-Regular.ttf") >>=
embedFile) 0
dracula = $(makeRelativeToProject ("bench" </> "dracula.txt") >>= embedStringFile)
main = defaultMain [
bgroup "Dracula" [
bench "Week-Head" $ whnf shapeStr dracula,
bench "Normal Form" $ nf shapeStr dracula,
bench "Paragraphs" $ nf (map shapeStr) $ Txt.lines dracula,
bench "Parallelised" $ nf (parMap rdeepseq shapeStr) $ Txt.lines dracula
],
bgroup "building blocks" [
bench "peekArray (NF)" $ nfIO $ Txt.useAsPtr (Txt.toStrict dracula) $
\ptr l -> peekArray (fromEnum l) ptr,
bench "peekArray" $ whnfIO $ Txt.useAsPtr (Txt.toStrict dracula) $
\ptr l -> peekArray (fromEnum l) ptr,
bench "alloc foreign ptr" $ whnfIO (mallocForeignPtrArray $
fromEnum $ Txt.length dracula :: IO (ForeignPtr Word8)),
bench "clone ptr" $ whnfIO $ Txt.useAsPtr (Txt.toStrict dracula) $
\ptr l -> clonePtr ptr $ fromEnum l,
bench "peek lazy" $ whnfIO (Txt.asForeignPtr (Txt.toStrict dracula) >>=
\(ptr, l) -> return $ peekLazy ptr $ fromEnum l),
bench "iterate lazy" $ whnfIO $ Txt.useAsPtr (Txt.toStrict dracula) $
\ptr l -> iterateLazy ptr $ fromEnum l,
bench "peek lazy (NF)" $ nfIO $ (Txt.asForeignPtr (Txt.toStrict dracula) >>=
\(ptr, l) -> return $ peekLazy ptr $ fromEnum l),
bench "iterate lazy (NF)" $ nfIO $ Txt.useAsPtr (Txt.toStrict dracula) $
\ptr l -> iterateLazy ptr $ fromEnum l,
-- These benchmarks give unconfident results, thought they'd be interesting...
bench "unsafePerformIO" $ whnf unsafePerformIO $ return (),
bench "unsafeDupablePerformIO" $ whnf unsafeDupablePerformIO $ return (),
bench "unsafeInterleaveIO" $ whnfIO $ unsafeInterleaveIO $ return (),
bench "accursedUnutterablePerformIO" $ whnf accursedUnutterablePerformIO $ return (),
bench "peek kilo array" $ nfIO $ Txt.useAsPtr (Txt.toStrict $ Txt.take 1024 dracula) $
\ptr l -> peekArray (fromEnum l) ptr,
bench "lazy kilo array" $ nfIO (Txt.asForeignPtr (Txt.toStrict $ Txt.take 1024 dracula) >>=
\(ptr, l) -> return $ peekLazy ptr $ fromEnum l)
]
]