Richard,<br><br>Wow and wow!<br><br>I&#39;m going to learn about hades.<br><br>   - Conal<br><br><div class="gmail_quote">On Wed, Aug 25, 2010 at 8:26 AM, Richard Smith <span dir="ltr">&lt;<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</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;">Hi,<br>
<div class="im"><br>
On Tue, August 24, 2010 10:14, Alexander Foremny wrote:<br>
&gt; When running worldB from main I can see the program&#39;s memory usage<br>
&gt; increasing and everything becomes very unresponsive. It seems as if whenE<br>
&gt; is accumalating all the occurences of the event. The problem seems to boil<br>
&gt; down to snapshot having the same behavior.<br>
&gt;<br>
&gt;&gt; snapshot (pure False) (atTimes [1..])<br>
&gt;<br>
&gt; This piece of code uses very much memory either. Is this due to<br>
&gt; reactive being broken (I read that somewhere) or is my solution just no<br>
&gt; solution at all?<br>
&gt;<br>
&gt; I am using ghc 6.12.1 with reactive 0.11.5 and reactive-glut 0.1.9.<br>
<br>
</div>Shameless plug alert...<br>
<br>
I&#39;ve attached my Haskell debugger hades &lt;<a href="http://control.monad.st/" target="_blank">http://control.monad.st/</a>&gt; to the<br>
following testcase:<br>
<br>
import Control.Applicative<br>
import FRP.Reactive<br>
import FRP.Reactive.LegacyAdapters<br>
<br>
foo = snapshot_ (pure (putStrLn &quot;Hi&quot;)) (atTimes [0.001,0.002..])<br>
main = adaptE foo &gt;&gt; adaptE foo<br>
<br>
Curious as to what is being retained, I did some poking around in the<br>
heap. Here&#39;s what I&#39;ve found:<br>
<br>
[... snip looking through backtrace ...]<br>
&gt; liftIO . putStr =&lt;&lt; prettyPrint 140513828164552<br>
$1 = foo/s2fC<br>
&gt; pointers 140513828164552<br>
[Ptr (RemotePtr 8279928),Ptr (RemotePtr 8324640)]<br>
&gt; liftIO . putStr =&lt;&lt; prettyPrint 8279928<br>
$1 = (,) (Imp $134 (exactNB/smWn $138 $133 $134)) (Stepper $141 ((,) (Imp<br>
$140 (exactNB/smWn $138 $139 $140)) (Stepper $141 ((,) (Imp $143<br>
(exactNB/smWn $138 $142 $143)) (Stepper $141 ((,) (Imp $145 (exactNB/smWn<br>
$138 $144 $145)) (Stepper $141 ((,) (Imp $147 (exactNB/smWn $138 $146<br>
$147)) (Stepper $141 ((,) (Imp $149 (exactNB/smWn $138 $148 $149))<br>
(Stepper $141 ((,) (Imp $151 (exactNB/smWn $138 $150 $151)) (Stepper $141<br>
((,) (Imp $153 (exactNB/smWn $138 $152 $153)) ([...snip...]<br>
[...]<br>
$133 = 1.0e-3<br>
$134 = (NoBound $133)<br>
$135 = &#39;H&#39;<br>
$136 = (FileHandle $80 $81)<br>
$137 = (hPutStr1 $120 ((,) NoBuffering $121) $122 (hPutStr2 $123 $124)<br>
(hPutStr_$s$wa1 $127 $126) (hPutStr_$s$wa $127 $128))<br>
$138 = (&lt;instance field OrdAddBounds_&lt;=&gt; $2 (amb2 (forkIO2 (childHandler1<br>
$24 $25 $26 $27 ($Lr3Ktlvl23 $23))) $31 (catches1 $31) (finally1 $31)<br>
((Handler $32 writeWord64OffPtr1/r1uF):((Handler $131<br>
writeWord64OffPtr1/r1uJ):((Handler (&lt;dict for Exception&gt; $53 $54 ($LrXBa7<br>
$52) $57) (&lt;instance field ShowNonTermination2&gt;/r1uL)):((Handler $132<br>
$Lr1yylvl1/r1uP):((Handler (&lt;dict for Exception&gt; $75 $76 ($LrXVa12 $74)<br>
$79) ($Lr1yylvl1/r1uR (writeWord64OffPtr1/r1uD $136 $123 $137 $129<br>
&#39;&quot;&#39;:$130))):$9))))) (SomeException $131 BothBottom) (SomeException $132<br>
DontBother)))<br>
$139 = 2.0e-3<br>
$140 = (NoBound $139)<br>
$141 = (main8 $123 $135:$50:$9 $136 $137)<br>
$142 = 3.0e-3<br>
$143 = (NoBound $142)<br>
$144 = 4.0e-3<br>
$145 = (NoBound $144)<br>
$146 = 5.0e-3<br>
$147 = (NoBound $146)<br>
$148 = 6.0e-3<br>
$149 = (NoBound $148)<br>
$150 = 7.0e-3<br>
$151 = (NoBound $150)<br>
$152 = 8.0e-3<br>
$153 = (NoBound $152)<br>
<br>
So (obviously in retrospect), foo is retaining an object of this form:<br>
<br>
(Imp (exactNB/smWn (NoBound 1.0e-3)), Stepper main8<br>
 (Imp (exactNB/smWn (NoBound 2.0e-3)), Stepper main8 (..., ...)))<br>
<br>
Here, main8 looks to be the (putStrLn &quot;Hi&quot;) computation.<br>
<br>
<br>
A slight tweak to the code should sort this out:<br>
<br>
foo () = snapshot_ (pure (putStrLn &quot;Hi&quot;)) (atTimes [0.001,0.002..])<br>
main = adaptE (foo ()) &gt;&gt; adaptE (foo ())<br>
<br>
Now I no longer see the space leak. In hades, I can&#39;t even find a<br>
reference to foo (presumably it got inlined out of existence). The event&#39;s<br>
list now looks like this (start from $209):<br>
<br>
$195 = 25.91600000000869<br>
$196 = (NoBound $195)<br>
$209 = listEG/sigh $210 $211<br>
$210 = (Imp $196 (exactNB/smWn $216 $195 $196))<br>
$211 = &lt;instance field FunctorEventG_fmap&gt;/siFL (withTimeE1 $212) $213<br>
$212 = exactNB1<br>
$213 = listEG/sigh $210 (Stepper () $214)<br>
$214 = &lt;worker for untilE&gt;/sgyB $215 (&lt;worker for untilE&gt;/sfAZ $228 (Imp<br>
$227 (atTimes3 $216)))<br>
$215 = foldr/s2p1 (atTimes1 $216) $217<br>
$216 = (&lt;instance field OrdAddBounds_&lt;=&gt; $204 $201)<br>
$217 = &lt;worker for %&gt;/s8ah $195 25.91700000000869 $218 $219 (&lt;worker for<br>
%&gt;/s3ts $218 $219)<br>
$218 = plusDouble<br>
$219 = minusDouble<br>
<br>
<br>
I hope this gives you enough insight to be able to fix your code!<br>
<br>
Regards,<br>
Richard Smith<br>
<br>
_______________________________________________<br>
Reactive mailing list<br>
<a href="mailto:Reactive@haskell.org">Reactive@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/reactive" target="_blank">http://www.haskell.org/mailman/listinfo/reactive</a><br>
</blockquote></div><br>