1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-}
import Criterion.Main
import qualified Data.ByteString as BSS
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Builder.Extra as BBE
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Double.Conversion.Convertable as BL
import Data.List (foldr)
import Data.Monoid ((<>))
import qualified Data.Text as T
import qualified Data.Text.Internal.Builder as BT
import qualified Data.Text.Lazy as TL
import Foreign.C.Types (CDouble(CDouble), CInt(CInt))
import qualified Text.Show.ByteString as BS
testList = [2.08345919 .. 20002.08345919] :: [Double]
testFloatList = [2.08345919 .. 20002.08345919] :: [Float]
testListBSBuilder :: (Double -> BB.Builder) -> [Double] -> BSS.ByteString
testListBSBuilder func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x <> ", ") <> y) mempty list
testListBSBuilderFloat :: (Float -> BB.Builder) -> [Float] -> BSS.ByteString
testListBSBuilderFloat func list = BSL.toStrict $ BBE.toLazyByteStringWith (BBE.safeStrategy 128 128) BSL.empty $ foldr (\x y -> (func x <> ", ") <> y) mempty list
testListByteString :: (Double -> BSS.ByteString) -> [Double] -> BSS.ByteString
testListByteString func = foldr (\x y -> (func x <> ", ") <> y) mempty
testListByteStringFloat :: (Float -> BSS.ByteString) -> [Float] -> BSS.ByteString
testListByteStringFloat func = foldr (\x y -> (func x <> ", ") <> y) mempty
testListText :: (Double -> T.Text) -> [Double] -> T.Text
testListText func = foldr (\x y -> (func x <> ", ") <> y) mempty
testListTextFloat :: (Float -> T.Text) -> [Float] -> T.Text
testListTextFloat func = foldr (\x y -> (func x <> ", ") <> y) mempty
testListTextBuilder :: (Double -> BT.Builder) -> [Double] -> T.Text
testListTextBuilder func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x <> ", ") <> y) mempty list
testListTextBuilderFloat :: (Float -> BT.Builder) -> [Float] -> T.Text
testListTextBuilderFloat func list = TL.toStrict $ BT.toLazyText $ foldr (\x y -> (func x <> ", ") <> y) mempty list
testFuncBuilderDefault :: [Double] -> BSS.ByteString
testFuncBuilderDefault = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.doubleDec x <> ", ") <> y) mempty list
testFuncBuilderDefaultFloat :: [Float] -> BSS.ByteString
testFuncBuilderDefaultFloat = \list -> BSL.toStrict $ BB.toLazyByteString $ foldr (\x y -> (BB.floatDec x <> ", ") <> y) mempty list
main = defaultMain [
bgroup "haskell-single" [
bench "show" $ nf show (pi::Double)
, bench "bytestring-show" $ whnf BS.show (pi::Double)
, bgroup "text" [
bench "toShortest" $ whnf (BL.toShortest :: Double -> T.Text) pi
, bench "toExponential" $ whnf ((BL.toExponential 3) :: Double -> T.Text) pi
, bench "toPrecision" $ whnf ((BL.toExponential 8) :: Double -> T.Text) pi
, bench "toFixed" $ whnf ((BL.toFixed 8) :: Double -> T.Text) pi
]
, bgroup "bytestring" [
bench "toShortest" $ whnf (BL.toShortest :: Double -> BSS.ByteString) pi
, bench "toExponential" $ whnf ((BL.toExponential 3) :: Double -> BSS.ByteString) pi
, bench "toPrecision" $ whnf ((BL.toExponential 8) :: Double -> BSS.ByteString) pi
, bench "toFixed" $ whnf ((BL.toFixed 8) :: Double -> BSS.ByteString) pi
]
, bgroup "bytestringBuilder" [
bench "toShortest" $ nf (BB.toLazyByteString . BL.toShortest) (pi::Double)
, bench "toPrecision" $ nf (BB.toLazyByteString . (BL.toExponential 8)) (pi::Double)
, bench "toPrecision" $ nf (BB.toLazyByteString . (BL.toPrecision 8)) (pi::Double)
, bench "toFixed" $ nf (BB.toLazyByteString . (BL.toFixed 8)) (pi::Double)
]
]
, bgroup "Haskell-list" [
bgroup "bytestring" [
bench "toShortest" $ nf (testListByteString BL.toShortest) testList
, bench "toExponential" $ nf (testListByteString $ BL.toExponential 8) testList
, bench "toPrecision" $ nf (testListByteString $ BL.toPrecision 8) testList
, bench "toFixed" $ nf (testListByteString $ BL.toFixed 8) testList]
, bgroup "bytestring-float" [
bench "toShortest" $ nf (testListByteStringFloat BL.toShortest) testFloatList
, bench "toExponential" $ nf (testListByteStringFloat $ BL.toExponential 8) testFloatList
, bench "toPrecision" $ nf (testListByteStringFloat $ BL.toPrecision 8) testFloatList
, bench "toFixed" $ nf (testListByteStringFloat $ BL.toFixed 8) testFloatList]
, bgroup "bytestring-builder" [
bench "toShortest" $ nf (testListBSBuilder BL.toShortest) testList
, bench "toExponential" $ nf (testListBSBuilder $ BL.toExponential 8) testList
, bench "toPrecision" $ nf (testListBSBuilder $ BL.toPrecision 8) testList
, bench "toFixed" $ nf (testListBSBuilder $ BL.toFixed 8) testList ]
, bgroup "bytestring-builder-float" [
bench "toShortest" $ nf (testListBSBuilderFloat BL.toShortest) testFloatList
, bench "toExponential" $ nf (testListBSBuilderFloat $ BL.toExponential 8) testFloatList
, bench "toPrecision" $ nf (testListBSBuilderFloat $ BL.toPrecision 8) testFloatList
, bench "toFixed" $ nf (testListBSBuilderFloat $ BL.toFixed 8) testFloatList ]
, bgroup "text" [
bench "toShortest" $ nf (testListText BL.toShortest) testList
, bench "toExponential" $ nf (testListText $ BL.toExponential 8) testList
, bench "toPrecision" $ nf (testListText $ BL.toPrecision 8) testList
, bench "toFixed" $ nf (testListText $ BL.toFixed 8) testList ]
, bgroup "text-float" [
bench "toShortest" $ nf (testListTextFloat BL.toShortest) testFloatList
, bench "toExponential" $ nf (testListTextFloat $ BL.toExponential 8) testFloatList
, bench "toPrecision" $ nf (testListTextFloat $ BL.toPrecision 8) testFloatList
, bench "toFixed" $ nf (testListTextFloat $ BL.toFixed 8) testFloatList ]
, bgroup "text-builder" [
bench "toShortest" $ nf (testListTextBuilder BL.toShortest) testList
, bench "toExponential" $ nf (testListTextBuilder $ BL.toExponential 8) testList
, bench "toPrecision" $ nf (testListTextBuilder$ BL.toPrecision 8) testList
, bench "toFixed" $ nf (testListTextBuilder $ BL.toFixed 8) testList ]
, bgroup "text-builder-float" [
bench "toShortest" $ nf (testListTextBuilderFloat BL.toShortest) testFloatList
, bench "toExponential" $ nf (testListTextBuilderFloat $ BL.toExponential 8) testFloatList
, bench "toPrecision" $ nf (testListTextBuilderFloat $ BL.toPrecision 8) testFloatList
, bench "toFixed" $ nf (testListTextBuilderFloat $ BL.toFixed 8) testFloatList ]
, bgroup "bytestring-builder-default" [
bench "Double" $ nf (testFuncBuilderDefault) testList
, bench "Float" $ nf (testFuncBuilderDefaultFloat) testFloatList ]
]
, bgroup "sprintf" [
bench "exact" $ whnf sprintf_exact pi
, bench "exponential" $ whnf (sprintf_exponential 3) pi
, bench "fixed" $ whnf (sprintf_fixed 8) pi
, bench "generic" $ whnf (sprintf_generic 6) pi
, bench "generic_default" $ whnf sprintf_generic_default pi
]
]
foreign import ccall unsafe sprintf_exact :: CDouble -> ()
foreign import ccall unsafe sprintf_exponential :: CInt -> CDouble -> ()
foreign import ccall unsafe sprintf_fixed :: CInt -> CDouble -> ()
foreign import ccall unsafe sprintf_generic :: CInt -> CDouble -> ()
foreign import ccall unsafe sprintf_generic_default :: CDouble -> ()
|