Daniel Franke | 1 May 2007 06:41
Picon
Favicon

Instantiating MonadPlus from ArrowApply and ArrowPlus


Is there any reason that the following is not defined in Control.Arrow?

instance (ArrowApply a, ArrowPlus a) => MonadPlus (ArrowMonad a) where
    mzero = ArrowMonad zeroArrow 
    mplus (ArrowMonad a) (ArrowMonad b) = ArrowMonad (a <+> b)

--

-- 
 Daniel Franke         df <at> dfranke.us         http://www.dfranke.us
 |----| =|\     \\\\    
 || * | -|-\---------   Man is free at the instant he wants to be. 
 -----| =|  \   ///     --Voltaire
Gorgonite | 1 May 2007 08:53
Picon

Translation of the Gentle Introduction to Haskell 98

Hello,

I don't know if there are French-speaking people reading this
mailing-list, but we at haskell-fr have some great news today !

We didn't find any French translation of the "Gentle Introduction to
Haskell" (version 98), thus we decide to write it.
Today, I would like to announce that  we have completed a translation into
French, that it can be read by following the link :

http://gorgonite.developpez.com/livres/traductions/haskell/gentle-haskell/

It is currently available as a set of HTML pages.  We are
also putting into the "official format" with *.verb files.
Hopefully you will soon be able to download that version as well.

Please send your comments and suggestions to the French Haskell
mailing list haskell-fr <at> haskell.org

Best regards,
Federico Squartini | 1 May 2007 13:59

Haskell fast (?) arrays

I was reading an old post where Hal Daume III was analyzing Haskell performance for arrays.
He proposed a test program which initializes an array, reverse it a number of times, and sums the contents.

So I wrote a c++ reference program, a naive haskell version using lists and I also tweaked a little bit with the IOArray version, which should be the fastest. Unfortunately there is a  huge performance gap. Haskell is slower by a factor of ten, even when using imperative style.

C++
time ./arrayC
499
real    0m0.059s
user    0m0.044s
sys    0m0.008s

HASKELL - IOUArray
time ./IOMutArrayUnboxed
499
real    0m0.720s
user    0m0.571s
sys    0m0.019s

HASKELL - list
time ./list
499
real    0m1.845s
user    0m1.770s
sys    0m0.064s


Can anyone suggest a faster version (using whatever data structure)? I like Haskell very much but I still have to figure out if the slowness of some code is due to my lack of knowledge or to some intrinsic limitation of the language (or libraries).

By the way, sorry for the poor quality of the code, I am not a computer scientist.


-------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------
//compile with
//g++ -o arrayC arrayC.cc
#include <stdio.h>
#include < math.h>



int main()
{
  int array[500001];
 
  for (int i=0;i<=500000;i++)
    {
    array[i]=(19*i+23)%911;
    }
  int tmp=0;
  for (int cnt=0;cnt<12;cnt++)
    {
      for (int x=0;x<=250000;x++)
        {
          tmp=array[500000-x];
          array[500000-x]=array[x];
          array[x]=tmp;
        }
    }
  int result=0;
  for (int i=0;i<=500000;i++)
    {
      result=result+(array[i]%911);
    }
  result=result % 911;
  printf("%d",result);
  return 0;
}

---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
-- compile with
-- ghc --make -o list list.hs
module Main
    where

testArray = [ (19*i+23) `mod` 911 |i <- [0..500000]]

sumArrayMod =  foldl (\x y -> (y+x) `mod` 911) 0

main = print $ sumArrayMod$
       reverse$ reverse$ reverse$ reverse$
       reverse$ reverse$ reverse$ reverse$
       reverse$ reverse$ reverse$ reverse$
       reverse$ reverse$ reverse$ reverse$
       testArray


---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
-- compile with
-- ghc --make -o IOMutArrayUnboxed IOMutArrayUnboxed.hs
module Main
    where

import Monad
import Data.Array.IO
import Data.Array.MArray
import Data.Array.Unboxed

total, semiTotal ::Int
total= 500000
semiTotal=250000


testArray :: IO (IOUArray Int Int)
testArray = newListArray (0,total)  [(19*i+23) `mod` 911 |i <- [0..total]]


reverseArray :: IOUArray Int Int -> IO ()
reverseArray arr = mapM_  (\i -> do oldi <- readArray arr i
                                    oldj <- readArray arr (total-i)
                                    writeArray arr i oldj
                                    writeArray arr (total-i) oldi)
                   [0..semiTotal]

sumArrayMod :: IOUArray Int Int -> IO Int
sumArrayMod arr = foldM (\s i -> do x <- readArray arr i
                                                          return   $!(s+x) `mod` 911) 0 [0..total]


main::IO()
main = testArray >>= \a ->
       reverseArray a >> reverseArray a >> reverseArray a >> reverseArray a >>
       reverseArray a >> reverseArray a >> reverseArray a >> reverseArray a >>
       reverseArray a >> reverseArray a >> reverseArray a >> reverseArray a >>
       reverseArray a >> reverseArray a >> reverseArray a >> reverseArray a >>
       sumArrayMod a >>=  print

---------------------------------------------------------------------------------------------------------

Federico


_______________________________________________
Haskell mailing list
Haskell <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell
Axel Simon | 1 May 2007 14:31
Picon
Favicon

Re: Haskell fast (?) arrays

Frederico,

On Tue, 2007-05-01 at 13:59 +0200, Federico Squartini wrote:
> I was reading an old post where Hal Daume III was analyzing Haskell
> performance for arrays. 
> He proposed a test program which initializes an array, reverse it a
> number of times, and sums the contents.
> 
> So I wrote a c++ reference program, a naive haskell version using
> lists and I also tweaked a little bit with the IOArray version, which
> should be the fastest. Unfortunately there is a  huge performance gap.
> Haskell is slower by a factor of ten, even when using imperative
> style. 

I think the version using lists is a bit unfair, since in C++ you don't
re-allocate the array on the heap and the Haskell version gives you a
very nice high-level abstraction of lists.

With respect to the imperative version, I would suggest

a) letting the program run for longer so you get more reliable timing.
b) use a similar optimisations that we've done for a demo of modifying
images in-situ for our Gtk2Hs library (in
http://darcs.haskell.org/gtk2hs/demo/fastdraw/FastDraw.hs ):

import Data.Array.Base ( unsafeWrite )

doFromTo 0 255 $ \y ->
  doFromTo 0 255 $ \x ->
    -- Here, writeArray was replaced with unsafeWrite. The latter does
    -- not check that the index is within bounds which has a tremendous
    -- effect on performance.
    --  writeArray  pbData (2+x*chan+y*row) blue  -- checked indexing
    unsafeWrite pbData (2+x*chan+y*row) blue  -- unchecked indexing

Here, doFromTo is much faster and using unsafeWrite instead of
writeArray eliminates the array bound check, which is a big win again.
Then again, it is questionable if you really want to do that kind of
low-level programming in Haskell.

Axel.
Stefan O'Rear | 1 May 2007 15:44
Picon

Re: Haskell fast (?) arrays

On Tue, May 01, 2007 at 01:59:01PM +0200, Federico Squartini wrote:
> I was reading an old post where Hal Daume III was analyzing Haskell
> performance for arrays.
> He proposed a test program which initializes an array, reverse it a number
> of times, and sums the contents.
> 
> So I wrote a c++ reference program, a naive haskell version using lists and
> I also tweaked a little bit with the IOArray version, which should be the
> fastest. Unfortunately there is a  huge performance gap. Haskell is slower
> by a factor of ten, even when using imperative style.

I'd recommend using -O2 or -O.  GHC doesn't even try to generate fast
code if you don't use them. 

Stefan
Federico Squartini | 1 May 2007 16:36

Re: Haskell fast (?) arrays

Of course I know that the list version is very unfair, but I wanted to see what was the trade off between elegance and speed.
Regarding whether low level programming makes sense or not, I was just curious to see what are the limits of Haskell. Moreover there is not much literature on high performance Haskell programming (tricks like unsafeWrite), at least organized in a systematic and concise way.

My original problem was writing a  fast library for simple matrix computations (i.e. multiplication and inversion for small dense matrices).  I have not been able to make GSLHaskell work with Lapack so far. :(

Anyway here are the new versions and timings, I increased the number of times the vector is reversed, I also compiled everything with -O2.

time ./arrayC
499
real    0m0.244s
user    0m0.236s
sys    0m0.005s

time ./list
499
real    0m11.036s
user    0m10.770s
sys    0m0.118s

time ./IOMutArrayUnboxed
499
real    0m2.573s
user    0m2.408s
sys    0m0.042s

time ./IOMutUnbUnsafe
499
real    0m2.264s
user    0m2.183s
sys    0m0.025s

------------------------------

--------------------------------------------------

//compile with g++ -O2 -o arrayC arrayC.cc
#include < stdio.h>
#include <math.h>



int main()
{
  int array[500001];
 
  for (int i=0;i<=500000;i++)
    {
    array[i]=(19*i+23)%911;
    }
  int tmp=0;
  for (int cnt=0;cnt<120;cnt++)
    {
      for (int x=0;x<=250000;x++)
        {
          tmp=array[500000-x];
          array[500000-x]=array[x];
          array[x]=tmp;
        }
    }
  int result=0;
  for (int i=0;i<=500000;i++)
    {
      result=result+(array[i]%911);
    }
  result=result % 911;
  printf("%d",result);
  return 0;
}

--------------------------------------------------------------------------------

-- compile with
-- ghc -O2 --make -o list list.hs

module Main
    where

import Data.List

testArray = [ (19*i+23) `mod` 911 |i <- [0..500000]]

sumArrayMod =  foldl (\x y -> (y+x) `mod` 911) 0

main = print $ sumArrayMod$
       foldl (.) id  (replicate 120 reverse) $testArray

--------------------------------------------------------------------------------------

-- compile with
-- ghc -O2 --make -o IOMutArrayUnboxed IOMutArrayUnboxed.hs
module Main
    where

import Monad
import Data.Array.IO
import Data.Array.MArray
import Data.Array.Unboxed

total, semiTotal ::Int
total= 500000
semiTotal=250000


testArray :: IO (IOUArray Int Int)
testArray = newListArray (0,total)  [(19*i+23) `mod` 911 |i <- [0..total]]


reverseArray :: IOUArray Int Int -> IO ()
reverseArray arr = mapM_  (\i -> do oldi <- readArray arr i
                                    oldj <- readArray arr (total-i)
                                    writeArray arr i oldj
                                    writeArray arr (total-i) oldi)
                   [0..semiTotal]

sumArrayMod :: IOUArray Int Int -> IO Int
sumArrayMod arr = foldM (\s i -> do x <- readArray arr i
                                    return   $!(s+x) `mod` 911) 0 [0..total]


main::IO()
main = testArray >>= \a ->
       sequence  (replicate 120 $reverseArray a)>>
       sumArrayMod a >>=  print

------------------------------------------------------------------------------------


-- compile with
-- ghc -O2 --make -o IOMutUnbUnsafe IOMutUnbUnsafe.hs
module Main
    where

import Monad
import Data.Array.IO
import Data.Array.MArray
import Data.Array.Unboxed
import Data.Array.Base ( unsafeWrite, unsafeRead )

total, semiTotal ::Int
total= 500000
semiTotal=250000


testArray :: IO (IOUArray Int Int)
testArray = newListArray (0,total)  [(19*i+23) `mod` 911 |i <- [0..total]]


reverseArray :: IOUArray Int Int -> IO ()
reverseArray arr = mapM_  (\i -> do oldi <- unsafeRead arr i
                                    oldj <- unsafeRead arr (total-i)
                                    unsafeWrite arr i oldj
                                    unsafeWrite arr (total-i) oldi)
                   [0..semiTotal]

sumArrayMod :: IOUArray Int Int -> IO Int
sumArrayMod arr = foldM (\s i -> do x <- unsafeRead arr i
                                    return   $!(s+x) `mod` 911) 0 [0..total]


main::IO()
main = testArray >>= \a ->
       doFromTo 1 120 (\_ -> reverseArray a) >> sumArrayMod a >>=  print



{-# INLINE doFromTo #-}
-- do the action for [from..to], ie it's inclusive.
doFromTo :: Int -> Int -> (Int -> IO ()) -> IO ()
doFromTo from to action =
  let loop n | n > to   = return ()
             | otherwise = do action n
                              loop (n+1)
   in loop from

-----------------------------------------------------------------------



_______________________________________________
Haskell mailing list
Haskell <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell
Donald Bruce Stewart | 1 May 2007 17:00
Picon
Picon
Favicon
Gravatar

Re: Haskell fast (?) arrays

federico.squartini:
> 
>    Of course I know that the list version is very unfair, but I
>    wanted to see what was the trade off between elegance and
>    speed.
>    Regarding whether low level programming makes sense or not,
>    I was just curious to see what are the limits of Haskell.
>    Moreover there is not much literature on high performance
>    Haskell programming (tricks like unsafeWrite), at least
>    organized in a systematic and concise way.
>    My original problem was writing a  fast library for simple
>    matrix computations (i.e. multiplication and inversion for
>    small dense matrices).  I have not been able to make
>    GSLHaskell work with Lapack so far. :(
>    Anyway here are the new versions and timings, I increased
>    the number of times the vector is reversed, I also compiled
>    everything with -O2.

Probably a good idea to use techniques from Data.ByteString (ie. use
strict Ptr loops, and Foreign arrays), or techniques from the shootout,
if you're chasing C speed. Good examples are:

    http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=ghc&id=4
    (mutable bit arrays)

    http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsieve&lang=ghc&id=0
    (mutable byte (foreign) arrays)

    http://shootout.alioth.debian.org/gp4/benchmark.php?test=spectralnorm&lang=ghc&id=4
    (more mutable arrays)

When I really really care about speed, I use 

    Foreign.Marshal.Array
    Data.ByteString

and apply ! patterns liberally, checking the Core output for inner
loops. -O2 -optc-O2 -optc-march=pentium4 often helps.

1-4x C is around what you can best hope for. 10x says "still room for
improvement" in my experience.

-- Don
Federico Squartini | 1 May 2007 17:01

Re: Haskell fast (?) arrays

Sorry, I was very silly!

This is the correct version of the program using the doFromto loop.
And it runs fast! I hope there are no further mistakes.
Thanks Axel.

time ./IOMutUnbUnsafe
499
real	0m0.708s
user	0m0.573s
sys	0m0.008s

-----------------------------------------------------------------------------
-- compile with
-- ghc --make -o IOMutUnbUnsafe IOMutUnbUnsafe.hs
module Main
    where

import Monad
import Data.Array.IO
import Data.Array.MArray
import Data.Array.Unboxed
import Data.Array.Base ( unsafeWrite, unsafeRead )

total, semiTotal ::Int
total= 500000
semiTotal=250000

testArray :: IO (IOUArray Int Int)
testArray = newListArray (0,total)  [(19*i+23) `mod` 911 |i <- [0..total]]

reverseArray :: IOUArray Int Int -> IO ()
reverseArray arr = doFromTo 0 semiTotal (\i -> do oldi <- unsafeRead arr i

         oldj <- unsafeRead arr (total-i)

         unsafeWrite arr i oldj

         unsafeWrite arr (total-i) oldi)

sumArrayMod :: IOUArray Int Int -> IO Int
sumArrayMod arr = foldM (\s i -> do x <- unsafeRead arr i
                                                         return
$!(s+x) `mod` 911) 0 [0..total]

main::IO()
main = testArray >>= \a ->
       doFromTo 1 120 (\_ -> reverseArray a) >> sumArrayMod a >>=  print

{-# INLINE doFromTo #-}
-- do the action for [from..to], ie it's inclusive.
doFromTo :: Int -> Int -> (Int -> IO ()) -> IO ()
doFromTo from to action =
  let loop n | n > to   = return ()
             | otherwise = do action n
                              loop (n+1)
   in loop from

-----------------------------------------------------------------------------------

Federico
Federico Squartini | 1 May 2007 17:23

Re: Haskell fast (?) arrays

Thanks for the hints. It's a pity that (as far as I know) no one has
written a tutorial on those techniques, because I think it would be
appreciated. Some of them are quite involved and learning them just by
reading code is very time consuming.

Federico
Rishiyur Nikhil | 1 May 2007 17:35
Favicon

Re: Haskell fast (?) arrays

I think another interesting data point would be for a C++ version
that uses the 'vector' data type from STL (Standard Template Library)
and using the vector indexing ops that do bounds-checking.

Regards,

Nikhil

_______________________________________________
Haskell mailing list
Haskell <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell

Gmane