myers-diff-0.3.0.0: bench-micro/Main.hs
{-# LANGUAGE BangPatterns #-}
module Main (main) where
import Control.Monad
import Criterion
import Criterion.Main
import Data.Maybe
import Data.String.Interpolate
import Data.Text as T
import Data.Text.Internal.Fusion
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as M
import Weigh
-- * Weight testing
testFunc :: Int -> Text -> Weigh ()
testFunc inputSize text = wgroup [i|#{inputSize} characters|] $ do
func' "VU.fromList" fromListMethod text
func' "VU.fromListN" fromListNMethod text
func' "generate" generateMethod text
func' "unfoldr" unfoldrMethod text
func' "unfoldrN" unfoldrNMethod text
func' "unfoldrExactN" unfoldrExactNMethod text
func' "stream" streamCreateMethod text
-- * Criterion testing
testGroup :: Int -> Text -> Benchmark
testGroup inputSize text =
bgroup [i|#{inputSize} characters|] [
bench "unfoldr" $ nf unfoldrMethod text
, bench "stream" $ nf streamCreateMethod text
-- , bench "VU.fromList" $ nf fromListMethod text
-- , bench "VU.fromListN" $ nf fromListNMethod text
-- , bench "generate" $ nf generateMethod text
-- , bench "unfoldrN" $ nf unfoldrNMethod text
-- , bench "unfoldrExactN" $ nf unfoldrExactNMethod text
]
-- * Methods
fromListMethod :: Text -> VU.Vector Char
fromListMethod = VU.fromList . T.unpack
fromListNMethod :: Text -> VU.Vector Char
fromListNMethod t = VU.fromListN (T.length t) (T.unpack t)
-- | This one has great allocation but it's O(n^2) time!
generateMethod :: Text -> VU.Vector Char
generateMethod t = VU.generate (T.length t) (T.index t)
unfoldrMethod :: Text -> VU.Vector Char
unfoldrMethod = VU.unfoldr T.uncons
unfoldrNMethod :: Text -> VU.Vector Char
unfoldrNMethod t = VU.unfoldrN (T.length t) T.uncons t
unfoldrExactNMethod :: Text -> VU.Vector Char
unfoldrExactNMethod t = VU.unfoldrExactN (T.length t) (fromJust . T.uncons) t
streamCreateMethod :: Text -> VU.Vector Char
streamCreateMethod t =
case stream t of
Stream step s0 _ -> VU.create $ do
m <- M.new (T.length t)
let
go s i =
case step s of
Done -> pure ()
Skip s' -> go s' i
Yield x s' -> do
M.write m i x
go s' (i + 1)
go s0 0
pure m
-- * Main
main :: IO ()
main = do
defaultMain [
testGroup n (T.replicate n "0") | n <- [10, 100, 1000, 10000, 100000]
-- testGroup n | n <- [10, 100, 1000, 10000, 100000]
]
mainWith $
forM_ [10, 100, 1000, 10000, 100000] $ \n -> do
let !text = T.replicate n "0"
testFunc n text