packages feed

bytestring-read-0.3.0: bench/main.hs

{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import Criterion.Main

import Data.ByteString(ByteString)
import qualified Data.ByteString.Char8 as SC
import qualified Data.ByteString.Lazy as L

import qualified Data.Text.Encoding as T

import Data.Scientific(toRealFloat)
import Data.String(IsString)

import qualified Data.ByteString.Read as R
import qualified Data.Text.Read as T
import qualified Data.ByteString.Lex.Double as Lex
import qualified Data.Attoparsec.ByteString.Char8 as A

short :: IsString s => s
short = "-2342395232123424.3424346343524e3"

long :: IsString s => s
long = "-234232345678976521345895325678987654321345678987654321345689643213595232123424.34243463435223456789321367899231808534492500740957389523850293482093852039587495203586329850238562834290374029844e3"

checkConsumed :: (IsString a, Eq a) => (v, a) -> v
checkConsumed (d, "") = d
checkConsumed _       = error "not consumed"

bytestringRead :: ByteString -> Double
bytestringRead = maybe (error "parse error") checkConsumed . R.signed R.fractional

lazyBytestringRead :: L.ByteString -> Double
lazyBytestringRead = maybe (error "parse error") checkConsumed . R.signed R.fractional

text :: ByteString -> Double
text = either (const $ error "parse error") checkConsumed . T.signed T.double . T.decodeUtf8

bytestringLexing :: ByteString -> Double
bytestringLexing = maybe (error "parse error") checkConsumed . Lex.readDouble

attoparsec :: ByteString -> Double
attoparsec = either (const $ error "parse error") id . A.parseOnly (fmap toRealFloat A.scientific)

read' :: ByteString -> Double
read' = read . SC.unpack

doBench :: IsString s => String -> (s -> Double) -> Benchmark
doBench n f = bgroup n
    [ bench "short" $ nf f short
    , bench "long"  $ nf f long
    ]

main :: IO ()
main = defaultMain
    [ doBench "bytestring-read" bytestringRead
    , doBench "bytestring-read(Lazy)" lazyBytestringRead
    , doBench "text" text
    , doBench "bytestring-lexing" bytestringLexing
    , doBench "attoparsec" attoparsec
    , doBench "read" read'
    ]