Did you compile with -O or -O2?<div><br><div class="gmail_quote">On Sat, May 9, 2009 at 6:50 PM, Kevin Haines <span dir="ltr">&lt;<a href="mailto:kevin.haines@ntlworld.com">kevin.haines@ntlworld.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi All,<br>
<br>
I&#39;m trying to write a bit of code that maps each byte in a block of Word8&#39;s to 3xWord8 using an array; i.e. mapping from 8 bit to 24 bit colour (this is an OpenGL application, and I&#39;m using textures).<br>
<br>
I should point out that this is experimental code, and I&#39;m still learning Haskell (and *loving* it, by the way!), so it probably looks a little unpolished.<br>
<br>
First, some data:<br>
<br>
data Palette = Palette { palRed :: Word8, palGrn :: Word8, palBlu :: Word8 }<br>
<br>
palette = listArray (0,49) paletteList<br>
paletteList = [<br>
            Palette 0 0 0,<br>
            Palette 0 0 0,<br>
            Palette 0 0 0,<br>
                .....<br>
<br>
<br>
<br>
Then, my first implementation, which took 57% time under profiling, was:<br>
<br>
loadTile :: Int -&gt; Int -&gt; IO (Ptr Word8)<br>
loadTile lat lon = do<br>
    terrainBytes &lt;- readTile lat lon<br>
<br>
    -- implementation #1<br>
    mapM_ (paletteMapper terrainBytes rgbBytes) [0..tileSize^2-1]<br>
<br>
    free terrainBytes<br>
    return rgbBytes<br>
<br>
    where tileSize = 128<br>
          paletteMapper :: Ptr Word8 -&gt; Ptr Word8 -&gt; Int -&gt; IO ()<br>
          paletteMapper tb rgb idx = do<br>
                v &lt;- peekElemOff tb idx<br>
                pokeByteOff rgb (idx*3) (palRed (palette!v))<br>
                pokeByteOff rgb (idx*3+1) (palGrn (palette!v))<br>
                pokeByteOff rgb (idx*3+2) (palBlu (palette!v))<br>
<br>
<br>
I tried moving paletterMapper out of the &#39;where&#39; clause and into the top level, which then took only 26% of time - i.e. half the time:<br>
<br>
<br>
paletteMapper :: Ptr Word8 -&gt; Ptr Word8 -&gt; Int -&gt; IO ()<br>
paletteMapper tb rgb idx = do<br>
   v &lt;- peekElemOff tb idx<br>
   pokeByteOff rgb (idx*3) (palRed (palette!v))<br>
   pokeByteOff rgb (idx*3+1) (palGrn (palette!v))<br>
  pokeByteOff rgb (idx*3+2) (palBlu (palette!v))<br>
<br>
loadTile :: Int -&gt; Int -&gt; IO (Ptr Word8)<br>
loadTile lat lon = do<br>
    terrainBytes &lt;- readTile lat lon<br>
<br>
    -- implementation #1<br>
    mapM_ (paletteMapper terrainBytes rgbBytes) [0..tileSize^2-1]<br>
<br>
    free terrainBytes<br>
    return rgbBytes<br>
<br>
    where tileSize = 128<br>
<br>
<br>
I don&#39;t understand why - the functions are the same, except for the scope they&#39;re in. Can anyone elaborate on what&#39;s happening?<br>
<br>
<br>
Incidentally, I now realise a faster way (14%) is:<br>
<br>
loadTile :: Int -&gt; Int -&gt; IO (Ptr Word8)<br>
loadTile lat lon = do<br>
<br>
    terrainBytes &lt;- readTile lat lon<br>
<br>
    rgbBytes &lt;- mallocBytes (3*(tileSize^2))<br>
    mapM_ (\x -&gt; do<br>
        v &lt;- peekElemOff terrainBytes x<br>
        pokeByteOff rgbBytes (x*3) (palRed (palette!v))<br>
        pokeByteOff rgbBytes (x*3+1) (palGrn (palette!v))<br>
        pokeByteOff rgbBytes (x*3+2) (palBlu (palette!v))<br>
        ) [0..tileSize^2-1]<br>
<br>
<br>
    free terrainBytes<br>
    return rgbBytes<br>
<br>
    where tileSize = 128<br>
<br>
<br>
(There may be faster/better ways still, I&#39;m all ears :-)<br>
<br>
Cheers<br>
<br>
Kevin<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</blockquote></div><br></div>