[Haskell-cafe] Generate random UArray in constant memory space.

Vasyl Pasternak vasyl.pasternak at gmail.com
Tue Feb 9 08:51:31 EST 2010


Sorry, maybe I should ask more clearer.

I've looked at dons article "Haskell as fast as C"[1], and tried to
implement similar algorithm but for list of random numbers.

Please look at code:

> import Text.Printf
> import Control.Applicative
> import System.Environment
> import Data.Array.Vector

> main = do
>   [size] <- map read <$> getArgs
>   let ints = enumFromToU 0 size :: UArr Int
>   printf "%d\n"  (sumU ints)

This code runs in constant space (on my pc ~25kb allocates on the
heap) regardless of array size. So I tried to achieve similar with
random list, just to replace `enumFromToU` with my own list generator.

So the question - is it possible to implement random list similary to
enumFromToU?


[1]http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/

Thank you,
Vasyl Pasternak

2010/2/9 Daniel Fischer <daniel.is.fischer at web.de>:
> Am Dienstag 09 Februar 2010 13:18:23 schrieb Vasyl Pasternak:
>> Hello Cafe,
>>
>> I tried to generate memory-efficient list of random numbers, so I've
>> used uvector library for this task. But it doesn't work,
>> it still allocates more than 6Gb of memory for the random list of 10
>>
>> million elements. Here is the code:
>
> Hmm,
>
> $ ghc -O2 --make ranVec
> [1 of 1] Compiling Main             ( ranVec.hs, ranVec.o )
> Linking ranVec ...
> $ ./ranVec 10000000 +RTS -sstderr
> 5130
>   4,919,912,080 bytes allocated in the heap
>         883,256 bytes copied during GC
>          26,896 bytes maximum residency (1 sample(s))
>          25,620 bytes maximum slop
>               1 MB total memory in use (0 MB lost due to fragmentation)
>
> maximum residency is just eight bytes more than for 100,000 or 1,000,000
> numbers. I think that is constant space.
>
> The ~5 GB total allocation is sequential, ten million new StdGens are
> produced and allocated, then immediately garbage collected. I see no
> problem (except that StdGen is slow, e.g. the Mersenne twister is much
> faster [and allocates less, but still linear in size]).
>
>> > import Text.Printf
>> > import System.Random
>> > import Control.Applicative
>> > import System.Environment
>> > import Data.Array.Vector
>> >
>> > randomListU :: (Int, Int) -> StdGen -> Int -> (UArr Int)
>> > randomListU b g size = unfoldU size gen g
>> >   where gen g = let (x, g') = randomR b g
>> >                 in JustS (x :*: g')
>> >
>> > main = do
>> >   [size] <- map read <$> getArgs
>> >   let ints = randomListU (-10, 10) (mkStdGen 1) size
>> >   printf "%d\n"  (sumU ints)
>>
>> Could someone give a hint, how to implement this function in constant
>> memory space?
>>
>> Thank you in advance.
>>
>> Best regards,
>> Vasyl Pasternak
>
>


More information about the Haskell-Cafe mailing list