4

I try to use Gloss.Raster.Array to effectively plot a set of points on a screen. It uses an Array D DIM2 Color as a container of points to plot. Currently it is a 500x500 array, representing a 'bitmap'.

Suppose that each frame I generate 1 new point to display.

I didn't find another way to adjust an existing repa array to contain a single new point rather than doing repa's traverse which looks approximately like this:

{-# INLINE traverseFn #-}
traverseFn px py = (\lookupfn i@(Z :. x :. y) -> 
    if x == px && y == py then red else lookupfn i)

newarr px py = R.traverse oldarr id (traverseFn px py)

I suspected this could turn to be rather inefficient: traversing whole 500x500 array for the sake of one point. But I thought maybe ghc will do some optimization magic and it won't.

Turns out it is. I tried to profile and it says that newarr takes 97.2% of time. And it works very slow too.

I'm kinda new to the whole haskell and repa ecosystem, taking my first steps, so I might not know something or do something wrong (either in my repo code or in my profiling attempts) - hence asking for help :)

Is there some performant way to change single value in repa array on each frame? Or if I want to add 500 points on each frame - what would be the answer then?

dimsuz
  • 8,969
  • 8
  • 54
  • 88
  • 2
    I don't think Repa has a mutable format, a reference to a memory area that can be mutated without copying the entire array. As a result even an operation that alters a single pixel either must copy the entire array or be a "delayed" array that will later need forced, which would cause a full copy even if the only delayed computation is the single pixel change. I suggest you use a mutable vector instead, perhaps with the `friday` library. – Thomas M. DuBuisson Mar 27 '16 at 23:30
  • @ThomasM.DuBuisson I do use delayed arrays for adding points. And this array is forced by gloss on each frame. So even if I do 500 delayed traverse-s (adding 500 pixels) or even if I modify my program to do adding 500 points in one traverse (using a State monad), no matter what the result will be copying a whole array on each frame. I see, thank you. – dimsuz Mar 28 '16 at 09:29
  • There's also yarr https://hackage.haskell.org/package/yarr - see here for examples https://github.com/leventov/yarr/tree/master/tests – idontgetoutmuch Mar 28 '16 at 18:41
  • @idontgetoutmuch I've heard about it, but I am using repa, because it is the only array library supported by gloss for easy rendering... – dimsuz Mar 30 '16 at 07:42

0 Answers0