diff --git a/Data/Vector/Binary.hs b/Data/Vector/Binary.hs
--- a/Data/Vector/Binary.hs
+++ b/Data/Vector/Binary.hs
@@ -1,5 +1,4 @@
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 --------------------------------------------------------------------
 -- |
 -- Module    : Data.Vector.Binary
@@ -15,6 +14,13 @@
 -- making it easy to serialize vectors to and from disk. We use the
 -- generic interface to vectors, so all vector types are supported.
 --
+-- All functions in this module use same data format. Different
+-- representations for vector length and its elements could be used
+-- but general shape is same.
+--
+-- > [number of elements]
+-- > [vector element    ] : N times
+--
 -- To serialize a vector:
 --
 -- > *Data.Vector.Binary> let v = Data.Vector.fromList [1..10]
@@ -29,71 +35,78 @@
 -- > Chunk "\US\139\b\NUL\NUL\N...\229\240,\254:\NUL\NUL\NUL" Empty
 --
 --------------------------------------------------------------------
-
-module Data.Vector.Binary () where
+module Data.Vector.Binary (
+    genericGetVector
+  , genericGetVectorWith
+  , genericPutVector
+  , genericPutVectorWith
+  ) where
 
 import Data.Binary
-import Control.Monad
 
-import qualified Data.Vector.Generic as G
-import qualified Data.Vector.Unboxed as U
-import qualified Data.Vector.Storable as S
+import qualified Data.Vector.Generic   as G
+import qualified Data.Vector.Unboxed   as U
+import qualified Data.Vector.Storable  as S
+import qualified Data.Vector.Primitive as P
 import Data.Vector (Vector)
 
-import System.IO.Unsafe
-import qualified Data.Vector.Generic.Mutable as M
 import Foreign.Storable (Storable)
 
 -- Enumerate the instances to avoid the nasty overlapping instances.
 
 -- | Boxed, generic vectors.
 instance Binary a => Binary (Vector a) where
-    put = putGeneric
-    get = getGeneric
+    put = genericPutVector
+    get = genericGetVector
     {-# INLINE get #-}
 
 -- | Unboxed vectors
 instance (U.Unbox a, Binary a) => Binary (U.Vector a) where
-    put = putGeneric
-    get = getGeneric
+    put = genericPutVector
+    get = genericGetVector
     {-# INLINE get #-}
 
+-- | Primitive vectors
+instance (P.Prim a, Binary a) => Binary (P.Vector a) where
+    put = genericPutVector
+    get = genericGetVector
+    {-# INLINE get #-}
+
 -- | Storable vectors
 instance (Storable a, Binary a) => Binary (S.Vector a) where
-    put = putGeneric
-    get = getGeneric
+    put = genericPutVector
+    get = genericGetVector
     {-# INLINE get #-}
 
 ------------------------------------------------------------------------
 
--- this is morally sound, if very awkward.
--- all effects are contained, and can't escape the unsafeFreeze
-getGeneric :: (G.Vector v a, Binary a) => Get (v a)
-{-# INLINE getGeneric #-}
-getGeneric = do
-    n  <- get
-
-    -- new unitinialized array
-    mv <- lift $ M.new n
-
-    let fill i
-            | i < n = do
-                x <- get
-                (unsafePerformIO $ M.unsafeWrite mv i x) `seq` return ()
-                fill (i+1)
-
-            | otherwise = return ()
+-- | Deserialize vector using custom parsers.
+genericGetVectorWith :: (G.Vector v a, Binary a)
+    => Get Int       -- ^ Parser for vector size
+    -> Get a         -- ^ Parser for vector's element
+    -> Get (v a)
+{-# INLINE genericGetVectorWith #-}
+genericGetVectorWith getN getA = do
+    n  <- getN
+    G.replicateM n getA
 
-    fill 0
+-- | Generic put for anything in the G.Vector class which uses custom
+--   encoders.
+genericPutVectorWith :: (G.Vector v a, Binary a)
+    => (Int -> Put)  -- ^ Encoder for vector size
+    -> (a   -> Put)  -- ^ Encoder for vector's element
+    -> v a -> Put
+{-# INLINE genericPutVectorWith #-}
+genericPutVectorWith putN putA v = do
+    putN (G.length v)
+    G.mapM_ putA v
 
-    lift $ G.unsafeFreeze mv
+-- | Generic function for vector deserialization.
+genericGetVector :: (G.Vector v a, Binary a) => Get (v a)
+{-# INLINE genericGetVector #-}
+genericGetVector = genericGetVectorWith get get
 
 -- | Generic put for anything in the G.Vector class.
-putGeneric :: (G.Vector v a, Binary a) => v a -> Put
-{-# INLINE putGeneric #-}
-putGeneric v = do
-    put (G.length v)
-    G.mapM_ put v
-
-lift :: IO b -> Get b
-lift = return .unsafePerformIO
+genericPutVector :: (G.Vector v a, Binary a) => v a -> Put
+{-# INLINE genericPutVector #-}
+genericPutVector = genericPutVectorWith put put
diff --git a/Data/Vector/Cereal.hs b/Data/Vector/Cereal.hs
deleted file mode 100644
--- a/Data/Vector/Cereal.hs
+++ /dev/null
@@ -1,84 +0,0 @@
-{-# LANGUAGE FlexibleInstances    #-}
-{-# LANGUAGE UndecidableInstances #-}
---------------------------------------------------------------------
--- |
--- Module    : Data.Vector.Cereal
--- Copyright : (c) Don Stewart 2010-2012
-
--- License   : BSD3
---
--- Maintainer: Don Stewart <dons00@gmail.com>
--- Stability : provisional
--- Portability: GHC only
---
--- Instances for Serialize for the types defined in the vector package,
--- making it easy to serialize vectors to and from disk. We use the
--- generic interface to vectors, so all vector types are supported.
---
---------------------------------------------------------------------
-
-module Data.Vector.Cereal () where
-
-import Data.Serialize
-import Control.Monad
-
-import qualified Data.Vector.Generic as G
-import qualified Data.Vector.Unboxed as U
-import qualified Data.Vector.Storable as S
-import Data.Vector (Vector)
-
-import System.IO.Unsafe
-import qualified Data.Vector.Generic.Mutable as M
-import Foreign.Storable (Storable)
-
--- | Boxed, generic vectors.
-instance Serialize a => Serialize (Vector a) where
-    put = putGeneric
-    get = getGeneric
-    {-# INLINE get #-}
-
--- | Unboxed vectors
-instance (U.Unbox a, Serialize a) => Serialize (U.Vector a) where
-    put = putGeneric
-    get = getGeneric
-    {-# INLINE get #-}
-
--- | Storable vectors
-instance (Storable a, Serialize a) => Serialize (S.Vector a) where
-    put = putGeneric
-    get = getGeneric
-    {-# INLINE get #-}
-
-------------------------------------------------------------------------
-
--- this is morally sound, if very awkward.
--- all effects are contained, and can't escape the unsafeFreeze
-getGeneric :: (G.Vector v a, Serialize a) => Get (v a)
-{-# INLINE getGeneric #-}
-getGeneric = do
-    n  <- get
-
-    -- new unitinialized array
-    mv <- lift $ M.new n
-
-    let fill i
-            | i < n = do
-                x <- get
-                (unsafePerformIO $ M.unsafeWrite mv i x) `seq` return ()
-                fill (i+1)
-
-            | otherwise = return ()
-
-    fill 0
-
-    lift $ G.unsafeFreeze mv
-
--- | Generic put for anything in the G.Vector class.
-putGeneric :: (G.Vector v a, Serialize a) => v a -> Put
-{-# INLINE putGeneric #-}
-putGeneric v = do
-    put (G.length v)
-    G.mapM_ put v
-
-lift :: IO b -> Get b
-lift = return .unsafePerformIO
diff --git a/benchmarks/Benchmarks.hs b/benchmarks/Benchmarks.hs
new file mode 100644
--- /dev/null
+++ b/benchmarks/Benchmarks.hs
@@ -0,0 +1,33 @@
+import Criterion.Main
+import Data.Binary
+
+import qualified Data.ByteString.Lazy     as BS
+import qualified Data.Vector.Unboxed as U
+import Data.Vector.Binary
+
+
+vec1,vec2,vec3 :: U.Vector Int
+vec1 = U.enumFromN 0 3
+vec2 = U.enumFromN 0 30
+vec3 = U.enumFromN 0 300
+
+bs1,bs2,bs3 :: BS.ByteString
+bs1 = encode vec1
+bs2 = encode vec2
+bs3 = encode vec3
+
+type V = BS.ByteString -> U.Vector Int
+
+main = defaultMain
+  [ bgroup "encode"
+    [ bench "U.Vector Int 3"   $ nf encode vec1
+    , bench "U.Vector Int 30"  $ nf encode vec2
+    , bench "U.Vector Int 300" $ nf encode vec3
+    ]
+  , bgroup "decode"
+    [ bench "U.Vector Int 3"   $ nf (decode :: V) bs1
+    , bench "U.Vector Int 30"  $ nf (decode :: V) bs2
+    , bench "U.Vector Int 300" $ nf (decode :: V) bs3
+    ]
+  ]
+
diff --git a/vector-binary-instances.cabal b/vector-binary-instances.cabal
--- a/vector-binary-instances.cabal
+++ b/vector-binary-instances.cabal
@@ -1,18 +1,6 @@
--- binary-vector-instances.cabal auto-generated by cabal init. For
--- additional options, see
--- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
--- The name of the package.
 Name:                vector-binary-instances
-
--- The package version. See the Haskell package versioning policy
--- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
--- standards guiding when and how versions should be incremented.
-Version:             0.2.1.0
-
--- A short (one-line) description of the package.
+Version:             0.2.1.1
 Synopsis:            Instances of Data.Binary and Data.Serialize for vector
-
--- A longer description of the package.
 Description:
    Instances for Binary for the types defined in the vector package,
    making it easy to serialize vectors to and from disk. We use the
@@ -36,50 +24,47 @@
 -- URL for the project homepage or repository.
 Homepage:            https://github.com/bos/vector-binary-instances
 bug-reports:         https://github.com/bos/vector-binary-instances/issues
-
--- The license under which the package is released.
 License:             BSD3
-
--- The file containing the license text.
 License-file:        LICENSE
-
--- The package author(s).
 Author:              Don Stewart
-
--- An email address to which users can send suggestions, bug reports,
--- and patches.
-Maintainer:          dons00@gmail.com, bos@serpentine.com
+Maintainer:          dons00@gmail.com, bos@serpentine.com, Ben Gamari <ben@smart-cactus.org>
 
 -- A copyright notice.
 -- Copyright:
 
 -- Stability of the pakcage (experimental, provisional, stable...)
 Stability:           Experimental
-
 Category:            Data
-
 Build-type:          Simple
 
--- Extra files to be distributed with the package, such as examples or
--- a README.
--- Extra-source-files:
-
 -- Constraint on the version of Cabal needed to build this package.
-Cabal-version:       >=1.6
+Cabal-version:       >=1.8
 
 
 Library
+  Ghc-options: -Wall
   -- Modules exported by the library.
   Exposed-modules:
-    Data.Vector.Binary,
-    Data.Vector.Cereal
+    Data.Vector.Binary
 
   -- Packages needed in order to build this package.
   Build-depends:
-    base > 3 && < 6,
-    vector >= 0.6,
+    base > 3 && < 4.10,
+    vector >= 0.6 && < 0.12,
+    binary >= 0.7 && < 0.9
+
+Benchmark benchmarks
+  Type:           exitcode-stdio-1.0
+  Main-is:        Benchmarks.hs
+  Build-depends:
+    base,
+    vector-binary-instances,
+    vector,
+    bytestring,
     binary,
-    cereal
+    criterion
+  hs-source-dirs: benchmarks
+
 
 source-repository head
   type:     git
