Source

text-format / benchmarks / Simple.hs

{-# LANGUAGE BangPatterns, OverloadedStrings #-}

module Main (main) where

import Control.Monad
import System.Environment
import Data.Text.Format as T
import Data.Time.Clock
import Data.Text.Lazy.Encoding
import qualified Data.ByteString.Lazy as L
import System.IO

counting :: Int -> (Int -> () -> IO ()) -> IO ()
counting count act = loop 0
    where loop !i | i < count = act i () >> loop (i+1)
                  | otherwise = return ()
{-# NOINLINE counting #-}
  
idle count = counting count $ \_ x -> return ()

plain count = counting count $ \_ x -> do
  L.putStr . encodeUtf8 $ "hi mom\n"

unit count = counting count $ \_ x -> do
  let t = T.format "hi mom\n" x
  L.putStr . encodeUtf8 $ t

int count = counting count $ \i x -> do
  let t = T.format "hi mom {}\n" (Only i)
  L.putStr . encodeUtf8 $ t

double count = counting count $ \i x -> do
  let t = T.format "hi mom {}\n" (Only (fromIntegral i * pi::Double))
  L.putStr . encodeUtf8 $ t

main = do
  args <- getArgs
  let count = case args of
                (_:x:_) -> read x
                _       -> 100000
  let bm = case args of
             ("idle":_)   -> idle
             ("plain":_)  -> plain
             ("unit":_)   -> unit
             ("double":_) -> double
             ("int":_)    -> int
             _            -> error "wut?"
  start <- getCurrentTime
  bm count
  elapsed <- (`diffUTCTime` start) `fmap` getCurrentTime
  T.hprint stderr "{} iterations in {} secs ({} thousand/sec)\n"
       (count, elapsed,
        fromRational (toRational count / toRational elapsed / 1e3) :: Double)