diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # bz2
 
+## 1.0.0.2
+
+  * Change buffering parameters for speed
+  * Add benchmarks relative to `bzlib`, `bzip-pipes`, `bzlib-conduit`
+
+## 1.0.0.1
+
+  * Pass `-O3` to `cc-options`
+
 ## 1.0.0.0
 
   * Remove `Codec.Compression.BZip.Foreign`
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 .PHONY: clean
 
 SHELL := bash
-MAKEFLAGS += --warn-undefined-variables --no-builtin-rules -j
+MAKEFLAGS += --warn-undefined-variables --no-builtin-rules
 .DELETE_ON_ERROR:
 
 setup: valgrind-3.15.0.tar
diff --git a/bench/Bench.cpphs b/bench/Bench.cpphs
new file mode 100644
--- /dev/null
+++ b/bench/Bench.cpphs
@@ -0,0 +1,76 @@
+{-# LANGUAGE PackageImports #-}
+
+module Main (main) where
+
+-- TODO: bench bzlib?
+import qualified "bz2" Codec.Compression.BZip   as BZ2
+#ifdef WITH_BZLIB
+import qualified "bzlib" Codec.Compression.BZip as BZlib
+#endif
+import           Conduit                        (runResourceT)
+import           Criterion.Main
+import qualified Data.ByteString.Lazy           as BSL
+import           Data.Conduit                   (runConduit, (.|))
+import qualified Data.Conduit.BZlib             as C
+import           Data.Conduit.Combinators       (sinkFile, sourceFile)
+import           Pipes                          (runEffect, (>->))
+import qualified Pipes.ByteString               as P
+import qualified Pipes.BZip                     as P
+import           Pipes.Safe                     (runSafeT)
+import           System.FilePath                ((</>))
+import           System.IO                      (IOMode (ReadMode, WriteMode), withFile)
+import           System.IO.Temp                 (withSystemTempDirectory)
+
+decompressDump :: (BSL.ByteString -> BSL.ByteString) -> IO ()
+decompressDump go = withSystemTempDirectory "bz2" $
+    \fp -> BSL.writeFile (fp </> "valgrind-3.15.0.tar") =<<
+        (go <$> BSL.readFile "valgrind-3.15.0.tar.bz2")
+
+compressDump :: (BSL.ByteString -> BSL.ByteString) -> IO ()
+compressDump go = withSystemTempDirectory "bz2" $
+    \fp -> BSL.writeFile (fp </> "valgrind-3.15.0.tar.bz2") =<<
+        (go <$> BSL.readFile "valgrind-3.15.0.tar")
+
+decompressDumpPipes :: IO ()
+decompressDumpPipes = withSystemTempDirectory "bz2" $ \fp ->
+    withFile "valgrind-3.15.0.tar.bz2" ReadMode $ \hIn ->
+        withFile (fp </> "valgrind-3.15.0.tar") WriteMode $ \hOut ->
+            runSafeT $ runEffect $ P.bunzip2 (P.fromHandle hIn) >-> P.toHandle hOut
+
+decompressDumpConduit :: IO ()
+decompressDumpConduit = withSystemTempDirectory "bz2" $ \fp ->
+    runResourceT $ runConduit $ sourceFile "valgrind-3.15.0.tar.bz2" .| C.bunzip2 .| sinkFile (fp </> "valgrind-3.15.0.tar")
+
+decompressFile :: FilePath -> IO BSL.ByteString
+decompressFile = fmap BZ2.decompress . BSL.readFile
+
+compressFile :: FilePath -> IO BSL.ByteString
+compressFile = fmap BZ2.compress . BSL.readFile
+
+main :: IO ()
+main =
+    defaultMain [ bgroup "decompressDump"
+                      [ bench "decompress + write to file (bz2)" $ nfIO (decompressDump BZ2.decompress)
+#ifdef WITH_BZLIB
+                      , bench "decompress + write to file (bzlib)" $ nfIO (decompressDump BZlib.decompress)
+#endif
+                      , bench "decompress + write to file (pipes-bzip)" $ nfIO decompressDumpPipes
+                      , bench "decompress + write to file (bzlib-conduit)" $ nfIO decompressDumpConduit
+                      ]
+                , bgroup "compressDump"
+                      [ bench "compress + write to file (bz2)" $ nfIO (compressDump BZ2.compress)
+#ifdef WITH_BZLIB
+                      , bench "compress + write to file (bzlib)" $ nfIO (compressDump BZlib.compress)
+#endif
+                      ]
+                , bgroup "decompress"
+                      [ bench "decompress file" $ nfIO (decompressFile "test/data/sample1.bz2")
+                      , bench "decompress file" $ nfIO (decompressFile "test/data/sample2.bz2")
+                      , bench "decompress file" $ nfIO (decompressFile "test/data/sample3.bz2")
+                      ]
+                , bgroup "compress"
+                      [ bench "compress file" $ nfIO (compressFile "test/data/sample1.ref")
+                      , bench "compress file" $ nfIO (compressFile "test/data/sample2.ref")
+                      , bench "compress file" $ nfIO (compressFile "test/data/sample3.ref")
+                      ]
+                ]
diff --git a/bench/Bench.hs b/bench/Bench.hs
deleted file mode 100644
--- a/bench/Bench.hs
+++ /dev/null
@@ -1,35 +0,0 @@
-module Main (main) where
-
--- TODO: bench bzlib?
-import qualified Codec.Compression.BZip as BZ2
-import           Criterion.Main
-import qualified Data.ByteString.Lazy   as BSL
-import           System.FilePath        ((</>))
-import           System.IO.Temp         (withSystemTempDirectory)
-
-decompressDump :: IO ()
-decompressDump = withSystemTempDirectory "bz2" $
-    \fp -> BSL.writeFile (fp </> "valgrind-3.15.0.tar") =<<
-        (BZ2.decompress <$> BSL.readFile "valgrind-3.15.0.tar.bz2")
-
-decompressFile :: FilePath -> IO BSL.ByteString
-decompressFile = fmap BZ2.decompress . BSL.readFile
-
-compressFile :: FilePath -> IO BSL.ByteString
-compressFile = fmap BZ2.compress . BSL.readFile
-
-main :: IO ()
-main =
-    defaultMain [ bgroup "decompressDump"
-                      [ bench "decompress + write to file" $ nfIO decompressDump ]
-                , bgroup "decompress"
-                      [ bench "decompress file" $ nfIO (decompressFile "test/data/sample1.bz2")
-                      , bench "decompress file" $ nfIO (decompressFile "test/data/sample2.bz2")
-                      , bench "decompress file" $ nfIO (decompressFile "test/data/sample3.bz2")
-                      ]
-                , bgroup "compress"
-                      [ bench "compress file" $ nfIO (compressFile "test/data/sample1.ref")
-                      , bench "compress file" $ nfIO (compressFile "test/data/sample2.ref")
-                      , bench "compress file" $ nfIO (compressFile "test/data/sample3.ref")
-                      ]
-                ]
diff --git a/bz2.cabal b/bz2.cabal
--- a/bz2.cabal
+++ b/bz2.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.18
 name:               bz2
-version:            1.0.0.1
+version:            1.0.0.2
 license:            BSD3
 license-file:       LICENSE
 copyright:          Copyright: (c) 2020 Vanessa McHale
@@ -8,7 +8,7 @@
 author:             Vanessa McHale
 bug-reports:        https://hub.darcs.net/vmchale/bz2/issues
 synopsis:           Bindings to libbz2
-description:        High-level bindings to libbz2 using c2hs and ByteString
+description:        High-level bindings to libbz2 via ByteString
 category:           Compression
 build-type:         Simple
 data-files:
@@ -36,6 +36,10 @@
     default:     False
     manual:      True
 
+flag with-bzlib
+    description:
+        Bench against [bzlib](http://hackage.haskell.org/package/bzlib)
+
 library
     exposed-modules:  Codec.Compression.BZip
     cc-options:       -O3
@@ -63,7 +67,7 @@
     install-includes: cbits/bzlib.h
     ghc-options:      -Wall
     build-depends:
-        base >=4.4 && <5,
+        base >=4.7 && <5,
         bytestring -any
 
     if !flag(cross)
@@ -106,18 +110,32 @@
         ghc-options: -Wcpp-undef
 
 benchmark bz2-bench
-    type:             exitcode-stdio-1.0
-    main-is:          Bench.hs
-    hs-source-dirs:   bench
-    default-language: Haskell2010
-    ghc-options:      -threaded -rtsopts -with-rtsopts=-N -O3 -Wall
+    type:               exitcode-stdio-1.0
+    main-is:            Bench.hs
+    build-tool-depends: cpphs:cpphs -any
+    hs-source-dirs:     bench
+    default-language:   Haskell2010
+    other-extensions:   PackageImports
+    ghc-options:        -threaded -rtsopts -with-rtsopts=-N -O3 -Wall
     build-depends:
         base -any,
         bz2 -any,
         criterion -any,
         filepath -any,
         temporary -any,
+        pipes-bzip,
+        pipes-bytestring,
+        pipes,
+        pipes-safe,
+        bzlib-conduit,
+        conduit >=1.3.0,
         bytestring -any
+
+    if flag(with-bzlib)
+        build-depends: bzlib -any
+
+    if flag(with-bzlib)
+        cpp-options: -DWITH_BZLIB
 
     if impl(ghc >=8.0)
         ghc-options:
diff --git a/src/Codec/Compression/BZip/Pack.chs b/src/Codec/Compression/BZip/Pack.chs
--- a/src/Codec/Compression/BZip/Pack.chs
+++ b/src/Codec/Compression/BZip/Pack.chs
@@ -89,12 +89,12 @@
         keepBytesAlive :: Ptr BzStream -> Maybe BS.ByteString -> [BS.ByteString] -> (BZAction -> IO BZError) -> IO (BZError, Maybe BS.ByteString, [BS.ByteString])
         keepBytesAlive _ Nothing [] act = (, Nothing, []) <$> act BzFinish
         keepBytesAlive _ Nothing bs' act = (, Nothing, bs') <$> act BzRun
-        keepBytesAlive _ passFwd@(Just b) [] act = do
-            BS.unsafeUseAsCStringLen b $ \_ -> do
+        keepBytesAlive _ passFwd@(Just b) [] act =
+            BS.unsafeUseAsCStringLen b $ \_ ->
 
                 (, passFwd, []) <$> act BzFinish
-        keepBytesAlive _ passFwd@(Just b) bs' act = do
-            BS.unsafeUseAsCStringLen b $ \_ -> do
+        keepBytesAlive _ passFwd@(Just b) bs' act =
+            BS.unsafeUseAsCStringLen b $ \_ ->
 
                 (, passFwd, bs') <$> act BzRun
 
@@ -109,7 +109,7 @@
                 (, Just b, bs') <$> act BzRun
 
 bufSz :: Integral a => a
-bufSz = 32 * 1024
+bufSz = 16 * 1024
 
 bzCompressInit :: CInt -> CInt -> ForeignPtr BzStream -> IO ()
 bzCompressInit blkSize wf ptr' = do
diff --git a/src/Codec/Compression/BZip/Unpack.chs b/src/Codec/Compression/BZip/Unpack.chs
--- a/src/Codec/Compression/BZip/Unpack.chs
+++ b/src/Codec/Compression/BZip/Unpack.chs
@@ -48,24 +48,24 @@
                 withForeignPtr pForeign $ \p ->
                     withForeignPtr bufOutForeign $ \bufOut -> do
 
-                            let act = do
+                        let act = do
 
-                                    {# set bz_stream.avail_out #} p bufSz
-                                    {# set bz_stream.next_out #} p (castPtr bufOut)
+                                {# set bz_stream.avail_out #} p bufSz
+                                {# set bz_stream.next_out #} p (castPtr bufOut)
 
-                                    bZ2BzDecompress ptr'
+                                bZ2BzDecompress ptr'
 
-                            (ret, keepAlive, bs'') <- step p passFwd bs' act
+                        (ret, keepAlive, bs'') <- step p passFwd bs' act
 
-                            szOut <- fromIntegral <$> {# get bz_stream->avail_out #} p
+                        szOut <- fromIntegral <$> {# get bz_stream->avail_out #} p
 
-                            let bytesAvail = bufSz - szOut
+                        let bytesAvail = bufSz - szOut
 
-                            newBSAp <- if bytesAvail /= 0
-                                then (:) <$> BS.packCStringLen (castPtr bufOut, bytesAvail)
-                                else pure id
+                        newBSAp <- if bytesAvail /= 0
+                            then (:) <$> BS.packCStringLen (castPtr bufOut, bytesAvail)
+                            else pure id
 
-                            pure (ret, szOut, newBSAp, bs'', keepAlive)
+                        pure (ret, szOut, newBSAp, bs'', keepAlive)
 
             let step' = if szOut == 0
                 then keepBytesAlive
@@ -78,7 +78,7 @@
         keepBytesAlive :: Ptr BzStream -> Maybe BS.ByteString -> [BS.ByteString] -> IO BZError -> IO (BZError, Maybe BS.ByteString, [BS.ByteString])
         keepBytesAlive _ Nothing bs' act = (, Nothing, bs') <$> act
         keepBytesAlive _ passFwd@(Just b) bs' act = do
-            BS.unsafeUseAsCStringLen b $ \_ -> do
+            BS.unsafeUseAsCStringLen b $ \_ ->
 
                 (, passFwd, bs') <$> act
 
@@ -93,12 +93,13 @@
                 (, Just b, bs') <$> act
 
 bufSz :: Integral a => a
-bufSz = 32 * 1024
+bufSz = 64 * 1024
 
 bzDecompressInit :: ForeignPtr BzStream -> IO ()
 bzDecompressInit ptr' = do
 
     withForeignPtr ptr' $ \p -> do
+
         {# set bz_stream.next_in #} p nullPtr
         {# set bz_stream.avail_in #} p 0
 
