loop performance bug

Sean Seefried sseefried at cse.unsw.edu.au
Mon Mar 14 20:13:41 EST 2005


This one might go even faster again.

Essentially due to Don Stewart but removes the bound checks and uses 
Int as an index.

---------
module Main
where

import Data.Array.MArray
import Data.Array.IO
import Data.Array.Base

import GHC.Base
import GHC.IOBase



forn a n | n >=# 10000# = return ()
             | otherwise    = fory a 0# >> forn a (n +# 1#)

fory a y | y >=# 100#   = return ()
          | otherwise    = forx a y 0# >> fory a (y +# 1#)

forx a y x | x >=# 100#   = return ()
            | otherwise    = do unsafeWrite a (I# ((y *# 100#) +# x)) 
False
                                forx a y (x +# 1#)

main :: IO ()
main = do
         (arr :: IOUArray Int Bool) <- newArray_ (0, 100*100-1)
         forn arr 0#
---------

I started working on one in which even the IO`s were unboxed. It didn't 
get any appreciable speed-up though. It looks like this:
---------
forn :: IOUArray Int Bool -> Int# -> IO ()
forn a n = IO $ forn' a n
   where
     forn' :: IOUArray Int Bool -> Int# -> State# RealWorld
           -> (# State# RealWorld, () #)
     forn' a 10000# s = (# s, () #)
     forn' a n s =
       case fory' a 0# s of
         (# s2, _ #) -> forn' a (n +# 1#) s2


     fory' :: IOUArray Int Bool -> Int# -> State# RealWorld
           -> (# State# RealWorld, () #)
     fory' a 100# s = (# s, () #)
     fory' a y s =
       case forx' a y 0# s of
         (# s2, _ #) -> fory' a (y +# 1#) s2

     forx' :: IOUArray Int Bool -> Int# -> Int# -> State# RealWorld
           -> (# State# RealWorld, () #)
     forx' a y 100# s = (# s, () #)
     forx' a y x s =
       case unIO (unsafeWrite a (I# ((y *# 100#) +# x)) False) of {
         writeArray' ->
       case writeArray' s of {
         (# s2, _ #) -> forx' a y (x +# 1#) s2 }}



main :: IO ()
main = do
         (arr :: IOUArray Int Bool) <- newArray_ (0, 100*100-1)
         forn arr 0#

---------

The called to unIO is an explicit unboxing of the result of 
unsafeWrite. You could probably speed this up even more by finding out 
how unsafeWrite was implemented and tweaking it a bit.

Of course, who wants to write code like this? I certainly don't. And I 
also believe that you shouldn't have to to get good performance.  I see 
the performance of Haskell arrays as a serious problem that still 
requires, despite much research, more attention.

Sean




More information about the Glasgow-haskell-bugs mailing list