uvector-0.1: tests/Performance.hs
{-# OPTIONS -O2 -optc-O -fglasgow-exts -optc-march=pentium4 #-}
{-# LANGUAGE BangPatterns #-}
import Text.Printf
import Control.Exception
import System.CPUTime
import System.IO
import Control.Monad.ST
import System
import Control.Monad
import Data.Bits
import Text.Printf
import Data.Array.Vector.ST
import Data.Array.Base
import GHC.Exts
import GHC.ST
------------------------------------------------------------------------
time :: IO t -> IO Double
time a = do
start <- getCPUTime
!v <- a
end <- getCPUTime
let diff = (fromIntegral (end - start)) / (10^12)
return diff
main = do
putStrLn "Starting..."
mapM_ run
[ ("nsieve-bits", time_nsieve 12)
]
putStrLn "Done."
run (s, a) = do
putStr (s++": ") >> hFlush stdout
t <- a
if t then do putStrLn "Ok."
else do putStrLn "Fail! New code was slower."
exitWith (ExitFailure 1)
------------------------------------------------------------------------
-- bitwise prime sive
time_nsieve n = do
!x <- (time (nsieve1 n))
!y <- (time (nsieve2 n))
return (x < y)
where
------------------------------------------------------------------------
-- PROGRAM 1
nsieve1 n = mapM_ (\i -> sieve1 (10000 `shiftL` (n-i))) [0, 1, 2]
sieve1 n = do
let r = runST (do t <- new n True
go t n 2 0)
n `seq` r `seq` return ()
go !a !m !n !c
| n == m = return c
| otherwise = do
e <- get a n
if e then let loop j
| j < m = do
x <- get a j
when x $ set a j False
loop (j+n)
| otherwise = go a m (n+1) (c+1)
in loop (n `shiftL` 1)
else go a m (n+1) c
{-
{-# INLINE newArrayT #-}
newArrayT n@(I# n#) t = ST $ \s1# ->
case newByteArray# (bOOL_SCALE n#) s1# of { (# s2#, marr# #) ->
case bOOL_WORD_SCALE n# of { n'# ->
let loop i# s3# | i# ==# n'# = s3#
| otherwise =
case writeWordArray# marr# i# e# s3# of { s4# ->
loop (i# +# 1#) s4# } in
case loop 0# s2# of { s3# ->
(# s3#, STUVector n marr# #) }}}
where
W# e# = if t then maxBound else 0 -- True
-}
------------------------------------------------------------------------
-- PROGRAM 2
nsieve2 n = mapM_ (\i -> sieve2 (10000 `shiftL` (n-i))) [0, 1, 2]
sieve2 n = do
let r = runST (do a <- newArray (2,n) True :: ST s (STUArray s Int Bool)
go2 a n 2 0)
n `seq` r `seq` return ()
go2 !a !m !n !c
| n == m = return c
| otherwise = do
e <- unsafeRead a n
if e then let loop j
| j < m = do
x <- unsafeRead a j
when x $ unsafeWrite a j False
loop (j+n)
| otherwise = go2 a m (n+1) (c+1)
in loop (n `shiftL` 1)
else go2 a m (n+1) c
------------------------------------------------------------------------