Daniel thank you for all your advice.<br><br>An additional ! bang pattern in convertIntToDouble fixed the issue! Also using a foldl&#39;<br>did the trick. <br><br>Now the program runs as it should with a constant amount of memory and in a very small amount of time. <br>
<br>I believe these problems are one of the major sources of frustration for Haskell newbies. Things that could work in &lt;X&gt; language easily suddenly become problems in Haskell. When you overcome these issues then you feel happy again that you chose Haskell as the main programming language of your research project. <br>
<br>Is there any guide that explains more about the &quot;bad consumption pattern&quot;. Are there any general rules defined to avoid these issues? It helped me to re-read the chapter on profiling in the Real World Haskell book to sorta understand the problem. Is there a more detailed definition of the problem than in RWH?<br>
<br>Regards,<br><br>Arnoldo<br><br><div class="gmail_quote">On Tue, Apr 20, 2010 at 2:49 AM, Daniel Fischer <span dir="ltr">&lt;<a href="mailto:daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Am Montag 19 April 2010 17:53:27 schrieb Arnoldo Muller:<br>
<div class="im">&gt; Hello Daniel:<br>
&gt;<br>
&gt; My % GC time is : 75.0%  (81.4% elapsed) and I am compiling with -O2.<br>
<br>
</div>Very bad. Can I see the code?<br>
<div class="im"><br>
&gt; Thank you for clarifying about the pointers.<br>
<br>
</div>Not to forget the Ints for counting.<br>
<div class="im"><br>
&gt;<br>
&gt; Slowly my memory grows up and eventually it explodes. I would expect<br>
&gt; that the list comprehension is lazily evaluated and therefore at any<br>
&gt; given time I am only executing one hamming distance. The result of the<br>
&gt; hamming distance is stored into a small statistics datatype I built<br>
&gt; (only stores sums and sum of squares and the counts). This datatype is<br>
&gt; updated using a foldr.<br>
<br>
</div>That might very well be the problem, if you update it with a foldr, you<br>
must construct the entire list of 2000^2 hamming-thunks before the work can<br>
begin.<br>
It&#39;s probably better to use foldl&#39; (and make the type strict) so you can<br>
start the work immediately.<br>
<div class="im"><br>
&gt;<br>
&gt; I have no idea where the leak is. What do you see in a .prof file to<br>
&gt; find a leak (hamming distance has the largest amount of time and %alloc)<br>
<br>
</div>For finding leaks, heap profiling (-h*) gives more info than -p. The .prof<br>
says more about where you spend your time than what hangs on to memory.<br>
<div class="im"><br>
&gt;  ? From my .prof file where would you start looking at?<br>
<br>
</div>- use hamming instead of hamming2<br>
- convertIntToDouble looks suspicious<br>
- calculating a few million Hamming distances takes some time, but what<br>
about getMyStats, should that really take 25%?<br>
<div class="im"><br>
<br>
&gt; &gt; &gt; filter (\x -&gt; x /= 0) $ map (uncurry hammingX) [(xs, ys) | xs &lt;-<br>
&gt; &gt; &gt; exampl, ys &lt;- exampl]<br>
&gt; &gt; &gt;<br>
<br>
</div>filter (/= 0) [hamming xs ys | xs &lt;- example, ys &lt;- example]<br>
<br>
And of course, you can trivially avoid half of the work.<br>
<div><div></div><div class="h5"><br>
&gt;<br>
&gt;<br>
&gt; Best Regards,<br>
&gt;<br>
&gt; Arnoldo Muller<br>
&gt;<br>
&gt; On Mon, Apr 19, 2010 at 3:18 AM, Daniel Fischer<br>
&lt;<a href="mailto:daniel.is.fischer@web.de">daniel.is.fischer@web.de</a>&gt;wrote:<br>
&gt; &gt; Am Montag 19 April 2010 01:03:14 schrieb Arnoldo Muller:<br>
&gt; &gt; &gt; Hello all:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; I want to generate some hamming distance statistics about a set of<br>
&gt; &gt; &gt; strings. As explained in another e-mail in this list, I used the<br>
&gt; &gt; &gt; following code to call the<br>
&gt; &gt; &gt; functions:<br>
&gt; &gt; &gt; (exampl holds the list of strings of size w)<br>
&gt; &gt; &gt; filter (\x -&gt; x /= 0) $ map (uncurry hammingX) [(xs, ys) | xs &lt;-<br>
&gt; &gt; &gt; exampl, ys &lt;- exampl]<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; I have two hamming functions:<br>
&gt; &gt; &gt; -- hamming distance for variable length strings<br>
&gt; &gt; &gt; hamming :: String -&gt; String -&gt; Int<br>
&gt; &gt; &gt; hamming x y = hamming&#39; x y 0<br>
&gt; &gt; &gt;     where<br>
&gt; &gt; &gt;       hamming&#39; [] _ !c = c<br>
&gt; &gt; &gt;       hamming&#39; _ [] !c = c<br>
&gt; &gt; &gt;       hamming&#39; (x:xs) (y:ys) !c<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;           | x == y = hamming&#39; xs ys c<br>
&gt; &gt; &gt;           | otherwise = hamming&#39; xs ys (c + 1)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; -- function posted in this mailing list<br>
&gt; &gt; &gt; hamming2 :: String -&gt; String -&gt; Int<br>
&gt; &gt; &gt; hamming2 xs ys = length (filter not (zipWith (==) xs ys))<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; I am executing these functions millions of times and the bottleneck<br>
&gt; &gt; &gt; of my program is in them as explained by running in profiling mode<br>
&gt; &gt; &gt; with +RTS -K400M -p -RTS<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; The costlier function is the hamming distance<br>
&gt; &gt; &gt; COST CENTRE                    MODULE               %time %alloc<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; hamming                        Distances             66.6   41.9<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; It says that it is performing 41% of the allocations. In the case of<br>
&gt; &gt; &gt; hamming2 the allocations go as far as 52%.<br>
&gt; &gt;<br>
&gt; &gt; Allocations are cheap, so that&#39;s not necessarily a problem. More<br>
&gt; &gt; important is, what&#39;s the maximum residency and how much is copied<br>
&gt; &gt; during GC? Are you compiling with -O2 ?<br>
&gt; &gt;<br>
&gt; &gt; &gt; I could understand that<br>
&gt; &gt; &gt; there are allocations in &quot;hamming2&quot; because we are creating pairs,<br>
&gt; &gt; &gt; but in the case of &quot;hamming&quot; there should be no allocation.<br>
&gt; &gt;<br>
&gt; &gt; Why not? I don&#39;t know how GHC counts allocations, but everytime you go<br>
&gt; &gt; from (x:xs) to xs, you need a new pointer to the tail. If that counts<br>
&gt; &gt; as allocation, hamming must allocate a lot, too.<br>
&gt; &gt;<br>
&gt; &gt; &gt; How can I execute my hamming functions without allocating memory?<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Best regards,<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Arnoldo Muller<br>
<br>
</div></div></blockquote></div><br>