{-# LANGUAGE BangPatterns #-}

module Bench.Vector.Algo.MutableSet
where

import Prelude hiding(length, read)

import Data.Vector.Mutable

mutableSet :: IOVector Int -> IO Int
{-# NOINLINE mutableSet #-}
mutableSet :: IOVector Int -> IO Int
mutableSet IOVector Int
v = do
  let repetitions :: Int
repetitions = Int
100 -- we repeat to reduce the standard deviation in measurements.
      l :: Int
l = IOVector Int -> Int
forall s a. MVector s a -> Int
length IOVector Int
v

      -- This function is tail recursive.
      f :: Int -> Int -> IO Int
      f :: Int -> Int -> IO Int
f Int
i !Int
curSum =
       if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
         then
           Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
curSum
         else do
           -- 'set' is what we want to benchmark.
           MVector (PrimState IO) Int -> Int -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> a -> m ()
set IOVector Int
MVector (PrimState IO) Int
v Int
i
           -- In order to make it difficult for ghc to optimize the 'set' call
           -- away, we read the value of one element and add it to a running sum
           -- which is returned by the function.
           Int
val <- MVector (PrimState IO) Int -> Int -> IO Int
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
read IOVector Int
MVector (PrimState IO) Int
v (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
           Int -> Int -> IO Int
f (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Int
curSumInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
val)
  Int -> Int -> IO Int
f Int
repetitions Int
0