diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Changes in 0.13.3.0
+
+  * Monadic variant of vector shuffle added: `uniformShuffleM`
+
+  * Context on `uniformShuffle` loosened
+
+
 Changes in 0.13.2.2
 
   * Fixed crash during gen. initialization on Windows when stderr
diff --git a/System/Random/MWC/Distributions.hs b/System/Random/MWC/Distributions.hs
--- a/System/Random/MWC/Distributions.hs
+++ b/System/Random/MWC/Distributions.hs
@@ -31,16 +31,16 @@
       -- * Permutations
     , uniformPermutation
     , uniformShuffle
-
+    , uniformShuffleM
     -- * References
     -- $references
     ) where
 
 import Prelude hiding (mapM)
-import Control.Monad (liftM,when)
+import Control.Monad (liftM)
 import Control.Monad.Primitive (PrimMonad, PrimState)
 import Data.Bits ((.&.))
-import Data.Foldable (Foldable,foldl')
+import Data.Foldable (foldl')
 import Data.Traversable (Traversable,mapM)
 import Data.Word (Word32)
 import System.Random.MWC (Gen, uniform, uniformR)
@@ -283,30 +283,42 @@
                    -> Gen (PrimState m)
                    -> m (v Int)
 {-# INLINE uniformPermutation #-}
-uniformPermutation n gen = do
-  when (n<=0) (pkgError "uniformPermutation" "size must be >0")
-  v <- G.unsafeThaw (G.generate n id :: v Int)
-  let lst = n-1
-      loop i | i == lst  = G.unsafeFreeze v
-             | otherwise = do
-                 j <- uniformR (i,lst) gen
-                 M.unsafeSwap v i j
-                 loop (i+1)
-  loop 0
-
+uniformPermutation n gen
+  | n < 0     = pkgError "uniformPermutation" "size must be >=0"
+  | otherwise = uniformShuffle (G.generate n id :: v Int) gen
 
--- | Random variate generator for a uniformly distributed shuffle of a
---   vector.
-uniformShuffle :: (PrimMonad m, G.Vector v a, G.Vector v Int)
+-- | Random variate generator for a uniformly distributed shuffle (all
+--   shuffles are equiprobable) of a vector. It uses Fisher-Yates
+--   shuffle algorithm.
+uniformShuffle :: (PrimMonad m, G.Vector v a)
                => v a
                -> Gen (PrimState m)
                -> m (v a)
 {-# INLINE uniformShuffle #-}
-uniformShuffle xs gen
-    | G.length xs <= 1 = return xs
-    | otherwise        = do
-        idx <- uniformPermutation (G.length xs) gen
-        return $! G.backpermute xs idx
+uniformShuffle vec gen
+  | G.length vec <= 1 = return vec
+  | otherwise         = do
+      mvec <- G.thaw vec
+      uniformShuffleM mvec gen
+      G.unsafeFreeze mvec
+
+-- | In-place uniformly distributed shuffle (all shuffles are
+--   equiprobable)of a vector.
+uniformShuffleM :: (PrimMonad m, M.MVector v a)
+                => v (PrimState m) a
+                -> Gen (PrimState m)
+                -> m ()
+{-# INLINE uniformShuffleM #-}
+uniformShuffleM vec gen
+  | M.length vec <= 1 = return ()
+  | otherwise         = loop 0
+  where
+    n   = M.length vec
+    lst = n-1
+    loop i | i == lst  = return ()
+           | otherwise = do j <- uniformR (i,lst) gen
+                            M.unsafeSwap vec i j
+                            loop (i+1)
 
 
 sqr :: Double -> Double
diff --git a/benchmarks/tsts.hs b/benchmarks/tsts.hs
new file mode 100644
--- /dev/null
+++ b/benchmarks/tsts.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE BangPatterns #-}
+import Control.Monad
+import System.Random.MWC
+import System.Random.MWC.Distributions
+
+main = do
+  withSystemRandom $ \g -> replicateM_ (300*1000) $ do
+    --
+    !n <- normal 0 1  g
+    !n <- normal 0 2  g
+    !n <- normal 3 3  g
+    !n <- normal 2 4  g
+    !n <- normal 2 5  g
+    !n <- normal 1 6  g
+    !n <- normal 3 7  g
+    !n <- normal 3 8  g
+    !n <- normal 3 9  g
+    !n <- normal 3 10 g
+    --
+    !n <- normal 0 1  g
+    !n <- normal 0 2  g
+    !n <- normal 3 3  g
+    !n <- normal 2 4  g
+    !n <- normal 2 5  g
+    !n <- normal 1 6  g
+    !n <- normal 3 7  g
+    !n <- normal 3 8  g
+    !n <- normal 3 9  g
+    !n <- normal 3 10 g
+    --
+    !n <- normal 0 1  g
+    !n <- normal 0 2  g
+    !n <- normal 3 3  g
+    !n <- normal 2 4  g
+    !n <- normal 2 5  g
+    !n <- normal 1 6  g
+    !n <- normal 3 7  g
+    !n <- normal 3 8  g
+    !n <- normal 3 9  g
+    !n <- normal 3 10 g
+    --
+    !n <- normal 0 1  g
+    !n <- normal 0 2  g
+    !n <- normal 3 3  g
+    !n <- normal 2 4  g
+    !n <- normal 2 5  g
+    !n <- normal 1 6  g
+    !n <- normal 3 7  g
+    !n <- normal 3 8  g
+    !n <- normal 3 9  g
+    !n <- normal 3 10 g
+    --
+    !n <- normal 0 1  g
+    !n <- normal 0 2  g
+    !n <- normal 3 3  g
+    !n <- normal 2 4  g
+    !n <- normal 2 5  g
+    !n <- normal 1 6  g
+    !n <- normal 3 7  g
+    !n <- normal 3 8  g
+    !n <- normal 3 9  g
+    !n <- normal 3 10 g
+    --
+    return () :: IO ()
+    
diff --git a/mwc-random.cabal b/mwc-random.cabal
--- a/mwc-random.cabal
+++ b/mwc-random.cabal
@@ -1,5 +1,5 @@
 name:           mwc-random
-version:        0.13.2.2
+version:        0.13.3.0
 synopsis:       Fast, high quality pseudo random number generation
 description:
   This package contains code for generating high quality random
