StRef is a boxed heap value.  <div><br></div><div>If you use a single element Unboxed Mutable vector you may find there's less boxing :)<span></span><br><br>On Saturday, June 18, 2016, Guillaume Bouchard <<a href="mailto:guillaum.bouchard%2Bhaskell@gmail.com">guillaum.bouchard+haskell@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello.<br>
<br>
I read a reddit post [0] which ends in a debate about haskell<br>
performances. Someone gives a C implementation which runs in 15ms on<br>
some dataset. I wanted to learn about mutable vector and ST and got<br>
something in haskell which runs in 50ms. Code is here [1].<br>
<br>
[0] <a href="https://www.reddit.com/r/haskell/comments/4ojsn0/counting_inversions_haskell/" target="_blank">https://www.reddit.com/r/haskell/comments/4ojsn0/counting_inversions_haskell/</a><br>
[1] <a href="https://github.com/guibou/inversionsCount/blob/syntax/inversions.hs" target="_blank">https://github.com/guibou/inversionsCount/blob/syntax/inversions.hs</a><br>
<br>
When I'm profiling the code, I'm surprised to see more than 50% of the<br>
%alloc in function which, from my point of view, must not allocate.<br>
<br>
For example, this function :<br>
<br>
inc :: forall s. STRef s Int -> ST s ()<br>
inc v = modifySTRef' v (+1)<br>
<br>
Is responsible for 10% of the allocation in this program. I was hoping<br>
that the "unboxing magic" of GHC may have replaced my Int somewhere by<br>
an unboxed one, but I guess the allocation means that the STRef is<br>
somehow pointing to a heap allocated Int.<br>
<br>
Do you know a way to remove theses allocations?<br>
<br>
As a second question, if you see any other way to improve this<br>
implementation, I'll be happy to learn something new ;)<br>
<br>
Finally, if you read my code, you'll see that I implemented a small<br>
DSL around ST / STRef / MVector to make my main function more<br>
readable. How do people write readable code in real life ?<br>
<br>
Especially, I was annoyed when I tried to convert this piece of C code :<br>
<br>
if (x1 < mid && (x2 == sz || tmp[x1] <= p[x2])) {<br>
    a;<br>
} else {<br>
   b;<br>
}<br>
<br>
In my haskell code, x1, x2 are STRef, and tmp and p are MVector. This<br>
was highly painful to write in haskell and I had to write something<br>
such as:<br>
<br>
x1 <- readSTRef x1'<br>
x2 <- readSTRef x2'<br>
<br>
cond <- if x1 < mid<br>
                 then if x2 == sz<br>
                           then return True<br>
                           else do<br>
                                tmp_x1 <- Vector.read tmp x1<br>
                                p_x2 <_ Vector.read p x2<br>
                                return (tmp_x1 <= p_x2)<br>
                 else return False<br>
if cond<br>
   then a<br>
   else b<br>
<br>
This is painful, complex and error prone, so is there another solution ?<br>
<br>
Thank you.<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="javascript:;" onclick="_e(event, 'cvml', 'Haskell-Cafe@haskell.org')">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>