packages feed

word16-0.1.0.0: bench/Bench.hs

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ViewPatterns #-}

module Main where

import GHC.ST
    ( ST (ST), runST )
import Criterion.Main
import GHC.Exts
import GHC.Word
import qualified Data.ByteString as BS
import qualified Data.ByteString.Short as S
import Data.ByteString.Short.Internal
import Data.Word16

asBA :: ShortByteString -> BA
asBA (SBS ba#) = BA# ba#

data BA = BA# ByteArray#
data MBA s = MBA# (MutableByteArray# s)


create :: Int -> (forall s. MBA s -> ST s ()) -> ShortByteString
create len fill =
    runST $ do
      mba <- newByteArray len
      fill mba
      BA# ba# <- unsafeFreezeByteArray mba
      return (SBS ba#)
{-# INLINE create #-}


main :: IO ()
main = do
    input <- S.toShort <$> BS.readFile "bench/Bench.hs"
    defaultMain [ 
        bench "Data.Word16" $ whnf (map' Data.Word16.toLower) input
      ]


map' :: (Word16 -> Word16) -> ShortByteString -> ShortByteString
map' f = \sbs ->
    let l = S.length sbs
        ba = asBA sbs
    in create (l * 2) (\mba -> go ba mba 0 l)
  where
    go :: BA -> MBA s -> Int -> Int -> ST s ()
    go !ba !mba !i !l
      | i >= l = return ()
      | otherwise = do
          let w = indexWord16Array ba i
          writeWord16Array mba i (f w)
          go ba mba (i+1) l
{-# INLINE map' #-}


writeWord16Array :: MBA s -> Int -> Word16 -> ST s ()
writeWord16Array (MBA# mba#) (I# i#) (W16# w#) =
  ST $ \s -> case writeWord16Array# mba# i# w# s of
               s' -> (# s', () #)

indexWord16Array :: BA -> Int -> Word16
indexWord16Array (BA# ba#) (I# i#) = W16# (indexWord16Array# ba# i#)

newByteArray :: Int -> ST s (MBA s)
newByteArray (I# len#) =
    ST $ \s -> case newByteArray# len# s of
                 (# s', mba# #) -> (# s', MBA# mba# #)

unsafeFreezeByteArray :: MBA s -> ST s BA
unsafeFreezeByteArray (MBA# mba#) =
    ST $ \s -> case unsafeFreezeByteArray# mba# s of
                 (# s', ba# #) -> (# s', BA# ba# #)