Skip to content

Commit

Permalink
Do not depend on dlist in tests/benchmarks (#420)
Browse files Browse the repository at this point in the history
* Make tests independent of dlist

* Make benchmarks independent of dlist
  • Loading branch information
Bodigrim authored Sep 11, 2021
1 parent b9b8725 commit e54d342
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 21 deletions.
15 changes: 12 additions & 3 deletions bench/BenchCSV.hs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ import Data.ByteString.Builder as B
import Data.ByteString.Builder.Prim.Internal ( (>*<), (>$<) )
import qualified Data.ByteString.Builder.Prim as E

-- To be used in a later comparison
import qualified Data.DList as D

-- bytestring benchmarks cannot depend on text because of a circular dependency.
-- Anyways these comparisons are of historical interest only, so disabled for now.
-- A curious soul can re-enable them by moving benchmarks to a separate package
Expand All @@ -136,6 +133,12 @@ import qualified Data.Text.Lazy.Builder as TB
import qualified Data.Text.Lazy.Builder.Int as TB
#endif

-- Same as above: comparison against DList is of historical interest now,
-- so lets shave off another dependency.
#ifdef MIN_VERSION_dlist
import qualified Data.DList as D
#endif

------------------------------------------------------------------------------
-- Simplife CSV Tables
------------------------------------------------------------------------------
Expand Down Expand Up @@ -334,6 +337,8 @@ benchBuilderEncodingUtf8 = bench "utf8 + renderTableBE maxiTable" $
-- Difference-list based rendering
------------------------------------------------------------------------------

#ifdef MIN_VERSION_dlist

type DString = D.DList Char

renderStringD :: String -> DString
Expand All @@ -360,6 +365,8 @@ benchDListUtf8 :: Benchmark
benchDListUtf8 = bench "utf8 + renderTableD maxiTable" $
nf (L.length . B.toLazyByteString . B.stringUtf8 . D.toList . renderTableD) maxiTable

#endif

------------------------------------------------------------------------------
-- Text Builder
------------------------------------------------------------------------------
Expand Down Expand Up @@ -406,7 +413,9 @@ benchCSV = bgroup "CSV"
[ benchNF
, benchString
, benchStringUtf8
#ifdef MIN_VERSION_dlist
, benchDListUtf8
#endif
#ifdef MIN_VERSION_text
, benchTextBuilder
, benchTextBuilderUtf8
Expand Down
2 changes: 0 additions & 2 deletions bytestring.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ test-suite test-builder
Data.ByteString.Builder.Tests
build-depends: base, bytestring, ghc-prim,
deepseq,
dlist >= 0.5,
transformers >= 0.3,
tasty,
tasty-hunit,
Expand Down Expand Up @@ -188,6 +187,5 @@ benchmark bytestring-bench
build-depends: base,
bytestring,
deepseq,
dlist,
tasty-bench,
random
48 changes: 32 additions & 16 deletions tests/builder/Data/ByteString/Builder/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import Foreign (minusPtr)

import Data.Char (chr)
import Data.Bits ((.|.), shiftL)
import qualified Data.DList as D
import Data.Foldable
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif
import Data.Word

import qualified Data.ByteString as S
Expand Down Expand Up @@ -228,31 +230,45 @@ data Strategy = Safe | Untrimmed
data Recipe = Recipe Strategy Int Int L.ByteString [Action]
deriving( Eq, Ord, Show )

newtype DList a = DList ([a] -> [a])

instance Semigroup (DList a) where
DList f <> DList g = DList (f . g)

instance Monoid (DList a) where
mempty = DList id
mappend = (<>)

fromDList :: DList a -> [a]
fromDList (DList f) = f []

toDList :: [a] -> DList a
toDList xs = DList (xs <>)

renderRecipe :: Recipe -> [Word8]
renderRecipe (Recipe _ firstSize _ cont as) =
D.toList $ evalState (execWriterT (traverse_ renderAction as)) firstSize
`D.append` renderLBS cont
fromDList $ evalState (execWriterT (traverse_ renderAction as)) firstSize <> renderLBS cont
where
renderAction :: Monad m => Action -> WriterT (D.DList Word8) (StateT Int m) ()
renderAction :: Monad m => Action -> WriterT (DList Word8) (StateT Int m) ()
renderAction (SBS Hex bs) = tell $ foldMap hexWord8 $ S.unpack bs
renderAction (SBS _ bs) = tell $ D.fromList $ S.unpack bs
renderAction (SBS _ bs) = tell $ toDList $ S.unpack bs
renderAction (LBS Hex lbs) = tell $ foldMap hexWord8 $ L.unpack lbs
renderAction (LBS _ lbs) = tell $ renderLBS lbs
renderAction (ShBS sbs) = tell $ D.fromList $ Sh.unpack sbs
renderAction (W8 w) = tell $ return w
renderAction (W8S ws) = tell $ D.fromList ws
renderAction (String cs) = tell $ foldMap (D.fromList . charUtf8_list) cs
renderAction Flush = tell $ D.empty
renderAction (EnsureFree _) = tell $ D.empty
renderAction (FDec f) = tell $ D.fromList $ encodeASCII $ show f
renderAction (DDec d) = tell $ D.fromList $ encodeASCII $ show d
renderAction (ShBS sbs) = tell $ toDList $ Sh.unpack sbs
renderAction (W8 w) = tell $ toDList [w]
renderAction (W8S ws) = tell $ toDList ws
renderAction (String cs) = tell $ foldMap (toDList . charUtf8_list) cs
renderAction Flush = tell $ mempty
renderAction (EnsureFree _) = tell $ mempty
renderAction (FDec f) = tell $ toDList $ encodeASCII $ show f
renderAction (DDec d) = tell $ toDList $ encodeASCII $ show d
renderAction (ModState i) = do
s <- lift get
tell (D.fromList $ encodeASCII $ show s)
tell (toDList $ encodeASCII $ show s)
lift $ put (s - i)

renderLBS = D.fromList . L.unpack
hexWord8 = D.fromList . wordHexFixed_list
renderLBS = toDList . L.unpack
hexWord8 = toDList . wordHexFixed_list

buildAction :: Action -> StateT Int Put ()
buildAction (SBS Hex bs) = lift $ putBuilder $ byteStringHex bs
Expand Down

0 comments on commit e54d342

Please sign in to comment.