{-# OPTIONS -fglasgow-exts #-}
-- ^ unboxed strings
--
-- Benchmark tool.
-- Compare a function against equivalent code from other libraries for
-- space and time.
--
import BenchUtils
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as L
import Data.List
import Data.Char
import Data.Word
import Data.Int
import System.IO
import Control.Monad
import Text.Printf
--
-- temporarily broken
--
main :: IO ()
main = do
-- initialise
force (fps,fps') >> force (lps,lps')
printf "# Size of test data: %dk\n" ((floor $ (fromIntegral (B.length fps)) / 1024) :: Int)
printf "#Byte\t Lazy\n"
run 5 ((fps,fps'),(lps,lps')) tests
------------------------------------------------------------------------
tests =
[ ("++",
[F ({-# SCC "append" #-} app (uncurry B.append))
,F ({-# SCC "lazy append" #-} app (uncurry L.append))
])
, ("concat",
[F ({-# SCC "concat" #-} app B.concat)
,F ({-# SCC "lazy concat" #-} app L.concat)
])
, ("length",
[F ({-# SCC "length" #-} app B.length)
,F ({-# SCC "lazy length" #-} app L.length)
])
-- , ("pack", [F (\_ -> {-# SCC "pack" #-} B.pack [1..1000000])
-- ])
, ("unpack", [F ({-# SCC "unpack" #-} app B.unpack)
])
{-
, ("compare",
[F ({-# SCC "compare" #-} app2 compare) :: needs type annotation
,F ({-# SCC "lazy compare" #-} app2 compare) ])
-}
, ("index",
[F ({-# SCC "index" #-} app$ flip B.index 260000)
,F ({-# SCC "lazy index" #-} app$ flip L.index 260000)
])
, ("map",
[F ({-# SCC "map" #-} app$ B.map (+1))
,F ({-# SCC "lazy map" #-} app$ L.map (+1))
])
, ("filter",
[F ({-# SCC "filter" #-} app$ B.filter (/=101))
,F ({-# SCC "lazy filter" #-} app$ L.filter (/=101))
])
-- , ("map'",
-- [F ({-# SCC "map" #-} app$ B.map (*2))
-- ,F ({-# SCC "map" #-} app$ B.map' (*1))
-- ])
-- , ("filter'",
-- [F ({-# SCC "filter" #-} app$ B.filter (/=121))
-- ,F ({-# SCC "filter'" #-} app$ B.filter' (/=121))
-- ])
-- , ("filterNotByte",
-- [F ({-# SCC "filterNotByte" #-}app$ B.filterNotByte 101)
-- ,F ({-# SCC "lazy filterNotByte" #-}app$ L.filterNotByte 101)
-- ])
-- , ("filterByte",
-- [F ({-# SCC "filterByte" #-} app$ B.filterByte 103)
--- ,F ({-# SCC "lazy filterByte" #-} app$ L.filterByte 103)
-- ])
-- , ("findIndexOrEnd",
-- [F ({-# SCC "findIndexOrEnd" #-} app$ B.findIndexOrEnd (==126))
-- ])
, ("findIndex",
[F ({-# SCC "findIndex" #-} app$ B.findIndex (==126))
,F ({-# SCC "lazy findIndex" #-} app$ L.findIndex (==126))
])
, ("find",
[F ({-# SCC "find" #-} app$ B.find (==126))
,F ({-# SCC "lazy find" #-} app$ L.find (==126))
])
, ("foldl",
[F ({-# SCC "fold" #-} app$ B.foldl (\a w -> a+1::Int) 0)
,F ({-# SCC "lazy fold" #-} app$ L.foldl (\a w -> a+1::Int) 0)
])
, ("foldl'",
[F ({-# SCC "fold" #-} app$ B.foldl' (\a w -> a+1::Int) 0)
,F ({-# SCC "lazy fold" #-} app$ L.foldl' (\a w -> a+1::Int) 0)
])
, ("take",
[F ({-# SCC "take" #-} app $ B.take 100000)
,F ({-# SCC "lazy take" #-} app $ L.take 100000)
])
, ("drop",
[F ({-# SCC "drop" #-} app $ B.drop 100000)
,F ({-# SCC "lazy drop" #-} app $ L.drop 100000)
])
, ("takeWhile",
[F ({-# SCC "takeWhile" #-} app $ B.takeWhile (/=122))
,F ({-# SCC "lazy takeWhile" #-} app $ L.takeWhile (==122))
])
, ("dropWhile",
[F ({-# SCC "dropWhile" #-} app $ B.dropWhile (/=122))
,F ({-# SCC "lazy dropWhile" #-} app $ L.dropWhile (/=122))
])
, ("span",
[F ({-# SCC "span" #-} app $ B.span (/=122))
,F ({-# SCC "lazy span" #-} app $ L.span (/=122))
])
, ("break",
[F ({-# SCC "break" #-} app $ B.break (==122))
,F ({-# SCC "lazy break" #-} app $ L.break (==122))
])
, ("split",
[F ({-# SCC "split" #-} app $ B.split 0x0a)
,F ({-# SCC "lazy split" #-} app $ L.split 0x0a)
])
-- , ("breakByte",
-- [F ({-# SCC "breakChar" #-} app $ B.breakByte 122)
-- ,F ({-# SCC "lazy breakChar" #-} app $ L.breakByte 122)
-- ])
-- , ("spanByte",
-- [F ({-# SCC "spanChar" #-} app $ B.spanByte 122)
-- ,F ({-# SCC "lazy spanChar" #-} app $ L.spanByte 122)
-- ])
, ("reverse",
[F ({-# SCC "reverse" #-} app B.reverse)
,F ({-# SCC "lazy reverse" #-} app L.reverse)
])
, ("cons",
[F ({-# SCC "cons" #-} app $ B.cons 120)
,F ({-# SCC "lazy cons" #-} app $ L.cons 120)
])
, ("snoc",
[F ({-# SCC "snoc" #-} app $ flip B.snoc 120)
,F ({-# SCC "lazy snoc" #-} app $ flip L.snoc 120)
])
, ("empty",
[F ({-# SCC "empty" #-} const B.empty)
,F ({-# SCC "lazy empty" #-} const L.empty)
])
, ("head",
[F ({-# SCC "head" #-} app B.head)
,F ({-# SCC "lazy head" #-} app L.head)
])
, ("tail",
[F ({-# SCC "tail" #-} app B.tail)
,F ({-# SCC "lazy tail" #-} app L.tail)
])
, ("last",
[F ({-# SCC "last" #-} app B.last)
,F ({-# SCC "lazy last" #-} app L.last)
])
, ("init",
[F ({-# SCC "init" #-} app B.init)
,F ({-# SCC "lazy init" #-} app L.init)
])
, ("count",
[F ({-# SCC "count" #-} app $ B.count 10)
,F ({-# SCC "lazy count" #-} app $ L.count 10)
])
, ("isPrefixOf",
[F ({-# SCC "isPrefixOf" #-} app $ B.isPrefixOf
(C.pack "The Project Gutenberg eBook"))
,F ({-# SCC "lazy isPrefixOf" #-} app $ L.isPrefixOf
(L.pack [84,104,101,32,80,114,111,106,101
,99,116,32,71,117,116,101,110,98
,101,114,103,32,101,66,111,111,107]))
])
, ("join",
[F ({-# SCC "join" #-} app $ B.join (B.pack [1,2,3]))
,F ({-# SCC "lazy join" #-} app $ L.join (L.pack [1,2,3]))
])
-- , ("joinWithByte",
-- [F ({-# SCC "joinWithByte" #-} app $ uncurry (B.joinWithByte 32))
-- ,F ({-# SCC "lazy joinWithByte" #-} app $ uncurry (L.joinWithByte 32))
-- ])
, ("any",
[F ({-# SCC "any" #-} app $ B.any (==120))
,F ({-# SCC "lazy any" #-} app $ L.any (==120))
])
, ("all",
[F ({-# SCC "all" #-} app $ B.all (==120))
,F ({-# SCC "lazy all" #-} app $ L.all (==120))
])
, ("maximum",
[F ({-# SCC "maximum" #-} app B.maximum)
,F ({-# SCC "lazy maximum" #-} app L.maximum)
])
, ("minimum",
[F ({-# SCC "minimum" #-} app B.minimum)
,F ({-# SCC "lazy minimum" #-} app L.minimum)
])
, ("elem",
[F ({-# SCC "elem" #-} app $ B.elem 122)
,F ({-# SCC "lazy elem" #-} app $ L.elem 122)
])
, ("notElem",
[F ({-# SCC "notElem" #-} app $ B.notElem 122)
,F ({-# SCC "lazy notElem" #-} app $ L.notElem 122)
])
, ("elemIndex",
[F ({-# SCC "elemIndex" #-} app $ B.elemIndex 122)
,F ({-# SCC "lazy elemIndex" #-} app $ L.elemIndex 122)
])
, ("findIndices",
[F ({-# SCC "findIndicies" #-} app $ B.findIndices (==122))
,F ({-# SCC "lazy findIndices" #-} app $ L.findIndices (==122))
])
, ("elemIndices",
[F ({-# SCC "elemIndicies" #-} app $ B.elemIndices 122)
,F ({-# SCC "lazy elemIndices" #-} app $ L.elemIndices 122)
])
, ("splitAt",
[F ({-# SCC "splitAt" #-} app $ B.splitAt 10000)
,F ({-# SCC "lazy splitAt" #-} app $ L.splitAt 10000)
])
, ("splitWith",
[F ({-# SCC "splitWith" #-} app $ B.splitWith (==122))
,F ({-# SCC "lazy splitWith" #-} app $ L.splitWith (==122))
])
, ("replicate",
[F ({-# SCC "replicate" #-} const $ B.replicate 10000000 120)
,F ({-# SCC "lazy replicate" #-} const $ L.replicate 10000000 120)
])
, ("group",
[F ({-# SCC "group" #-} app B.group)
,F ({-# SCC "lazy group" #-} app L.group)
])
, ("groupBy",
[F ({-# SCC "groupBy" #-} app $ B.groupBy (==))
,F ({-# SCC "lazy groupBy" #-} app $ L.groupBy (==))
])
, ("inits",
[F ({-# SCC "inits" #-} app B.inits)
])
, ("tails",
[F ({-# SCC "tails" #-} app B.tails)
])
-- , ("transpose",[F ({-# SCC "transpose" #-}B.transpose [fps,fps'])])
------------------------------------------------------------------------
--
-- Char8 or ByteString only
, ("intersperse",
[F ({-# SCC "intersperse" #-} app $ B.intersperse 120 )
])
, ("sort",
[F ({-# SCC "sort" #-} app B.sort)
])
-- , ("lineIndices",
-- [F ({-# SCC "lineIndicies" #-} app C.lineIndices)
-- ])
, ("elemIndexEnd",
[F ({-# SCC "elemIndexEnd" #-} app $ B.elemIndexEnd 122)
])
-- , ("breakSpace",
-- [F ({-# SCC "breakSpace" #-} app C.breakSpace)
-- ])
-- , ("dropSpace",
-- [F ({-# SCC "dropSpace" #-} app C.dropSpace)
-- ])
-- , ("dropSpaceEnd",
-- [F ({-# SCC "dropSpaceEnd" #-} app C.dropSpaceEnd)
-- ])
-- , ("zip",[F ({-# SCC "zip" #-} B.zip fps fps)])
, ("zipWith'",
[F ({-# SCC "zipWith'" #-} app (uncurry (B.zipWith (+))))
])
, ("isSubstringOf",
[F ({-# SCC "isSubstringOf" #-} app $ B.isSubstringOf (C.pack "email news"))
])
, ("isSuffixOf",
[F ({-# SCC "isSuffixOf" #-} app $ B.isSuffixOf (C.pack "new eBooks"))
])
, ("spanEnd",
[F ({-# SCC "spanEnd" #-} app $ B.spanEnd (/=122))
])
, ("lines",
[F ({-# SCC "lines" #-} app C.lines)
])
, ("unlines",
[F ({-# SCC "unlines" #-} app C.unlines)
])
, ("words",
[F ({-# SCC "words" #-} app C.words)
])
, ("unwords",
[F ({-# SCC "unwords" #-} app C.unwords)
])
]
------------------------------------------------------------------------
fst1 f ((x,_),_) = f x
snd1 f (_,(x,_)) = f x
fst2list f ((x,y),_) = f [x,y]
snd2list f (_,(x,y)) = f [x,y]
fst2 f (x,_) = f x
snd2 f (_,y) = f y
type Input = ((B.ByteString,B.ByteString),(L.ByteString,L.ByteString))
class (Eq a, Ord a) => Ap a where app :: (a -> b) -> Input -> b
instance Ap B.ByteString where app = fst1
instance Ap L.ByteString where app = snd1
instance Ap [B.ByteString] where app = fst2list
instance Ap [L.ByteString] where app = snd2list
instance Ap (B.ByteString, B.ByteString) where app = fst2
instance Ap (L.ByteString, L.ByteString) where app = snd2
app2 :: Ap (a, b) => (a -> b -> c) -> Input -> c
app2 = app . uncurry
|