diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
+module Main where
+
+import Criterion.Main as Criterion
+import Data.ByteString as Strict
+import Data.ByteString.Lazy as Lazy
+import Data.GenValidity
+import Data.GenValidity.ByteString ()
+import Data.GenValidity.Criterion
+
+main :: IO ()
+main =
+  Criterion.defaultMain
+    [ bgroup
+        "Instances"
+        [ genValidBench @Strict.ByteString,
+          genValidBench @Lazy.ByteString
+        ],
+      bgroup
+        "Approaches"
+        [ genBenchSizes "SB.pack <$> genValid" (Strict.pack <$> genValid),
+          genBenchSizes "LB.pack <$> genValid" (Lazy.pack <$> genValid)
+        ]
+    ]
diff --git a/genvalidity-bytestring.cabal b/genvalidity-bytestring.cabal
--- a/genvalidity-bytestring.cabal
+++ b/genvalidity-bytestring.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: d58a1f5690347e4438ecc4d4d0dd16378df86a6e507118ab2bd0f92416071cdf
+-- hash: e829149efdf6026d6246ee4a88e92b01272e80068931d575c245f5ba38e086b3
 
 name:           genvalidity-bytestring
-version:        0.5.0.1
+version:        0.6.0.0
 synopsis:       GenValidity support for ByteString
 category:       Testing
 homepage:       https://github.com/NorfairKing/validity#readme
@@ -35,6 +35,7 @@
     , base >=4.7 && <5
     , bytestring
     , genvalidity >=0.8
+    , random
     , validity >=0.5
     , validity-bytestring >=0.4
   default-language: Haskell2010
@@ -58,4 +59,22 @@
     , genvalidity-hspec
     , hspec
     , validity >=0.9
+  default-language: Haskell2010
+
+benchmark genvalidity-bytestring-bench
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  other-modules:
+      Paths_genvalidity_bytestring
+  hs-source-dirs:
+      bench/
+  ghc-options: -Wall
+  build-depends:
+      QuickCheck
+    , base >=4.7 && <5
+    , bytestring
+    , criterion
+    , genvalidity
+    , genvalidity-bytestring
+    , genvalidity-criterion
   default-language: Haskell2010
diff --git a/src/Data/GenValidity/ByteString.hs b/src/Data/GenValidity/ByteString.hs
--- a/src/Data/GenValidity/ByteString.hs
+++ b/src/Data/GenValidity/ByteString.hs
@@ -9,7 +9,11 @@
 
 import Data.GenValidity
 import Data.Validity.ByteString ()
+import System.Random as Random
 import Test.QuickCheck
+import Test.QuickCheck.Gen
+import Test.QuickCheck.Random
+import Data.Word (Word8)
 #if !MIN_VERSION_base(4,8,0)
 import Control.Applicative ((<*>), pure)
 import Data.Functor ((<$>))
@@ -27,7 +31,7 @@
 -- > genValid = SB.pack <$> genValid
 -- > shrinkValid = fmap SB.pack . shrinkValid . SB.unpack
 instance GenValid SB.ByteString where
-    genValid = SB.pack <$> genValid
+    genValid = genStrictByteStringBy genValid
     shrinkValid = fmap SB.pack . shrinkValid . SB.unpack
 #if MIN_VERSION_base(4,9,0)
 -- If you see this error and want to learn more, have a look at docs/BYTESTRING.md
@@ -36,6 +40,18 @@
     genUnchecked = error "unreachable"
     shrinkUnchecked = error "unreachable"
 #endif
+
+genStrictByteStringBy :: Gen Word8 -> Gen SB.ByteString
+genStrictByteStringBy (MkGen word8Func) = do
+  len <- genListLength
+  MkGen $ \qcgen size ->
+    let go :: QCGen -> Maybe (Word8, QCGen)
+        go qcg =
+          let (qc1, qc2) = Random.split qcg
+           in Just (word8Func qc1 size, qc2)
+     in fst $ SB.unfoldrN len go qcgen
+
+
 -- | WARNING: Unchecked ByteStrings are __seriously__ broken.
 --
 -- The pointer may still point to something which is fine, but
@@ -59,7 +75,7 @@
     [SB.PS p o' l' | (o', l') <- shrinkUnchecked (o, l)]
 
 instance GenValid LB.ByteString where
-    genValid = LB.pack <$> genValid
+    genValid = genLazyByteStringBy genValid
     shrinkValid = fmap LB.pack . shrinkValid . LB.unpack
 #if MIN_VERSION_base(4,9,0)
 -- If you see this error and want to learn more, have a look at docs/BYTESTRING.md
@@ -68,6 +84,19 @@
     genUnchecked = error "unreachable"
     shrinkUnchecked = error "unreachable"
 #endif
+
+genLazyByteStringBy :: Gen Word8 -> Gen LB.ByteString
+genLazyByteStringBy gen = genLazyByteStringByStrictByteString (genStrictByteStringBy gen)
+
+genLazyByteStringByStrictByteString :: Gen SB.ByteString -> Gen LB.ByteString
+genLazyByteStringByStrictByteString gen =
+  sized $ \s -> do
+    ss <- arbPartition s
+    go ss
+  where
+    go [] = pure LB.Empty
+    go (s:ss) = LB.Chunk <$> resize s gen <*> go ss
+
 -- | WARNING: Unchecked ByteStrings are __seriously__ broken.
 --
 -- See 'genTrulyUncheckedStrictByteString'
