<div dir="ltr"><div>Excellent timing :) and thanks for the feedback.<br><br></div>I realize this email has gotten pretty extensive. :) Open questions are in bold. <br><div><br><div><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I just tried converting the code to Typed Racket using types loose enough to ensure only functions needed to be annotated (i.e. mostly (Vectorof Fixnum) and Real). I also changed it to use `images/flomap', which is written in Typed Racket, instead of `picturing-programs', which is untyped and doesn't have a typed interface. (That basically meant changing `build-image' to `build-flomap*', and returning flvectors instead of colors from the callbacks.) It took me about 10 minutes and was straightforward. It would be a good first TR experiment.<br>
</blockquote><div><br></div><div>Real will work? (Well, considering you did it I'd assume so.) For whatever reason, I assumed that I would have to use Flonum to get the floating point optimizations, but that leads to the issues I had with 0 not typechecking from the other email. <br>
<br>In any case, I actually ran it. In practice, Real has essentially the same performance as Flonum without the annoying issue with 0, so that's good. So then when would you specifically want to use Flonum instead of Real?<br>
<br></div><div>Then I saw Float. At the moment, I'm not sure what the difference is between Flonum, Float, and Real, but using Flonum and Real have about the same runtime and Float is about twice as fast.<b> Why would that be the case?</b><br>
</div><div><br></div><div>I didn't actually know that images/flomap existed. I was looking for something that built an image from a generator function and picturing-programs was the only one that I could find. That's one downside of the Racket documentation (really documentation in general) is that it can occasionally be hard to find exactly what you're looking for if you don't know what it's called.<br>
<br></div><div><b>Is there a difference in build-flomap* between returning a flomap or a flvector or (Vectorof Float)?</b> I can't seem to get the latter working...<br></div><div><br></div><div>With the fastest code I've written, it's down to:<br>
<span style="font-family:courier new,monospace"> perlin: cpu time: 297 real time: 294 gc time: 109<br> simplex: cpu time: 156 real time: 159 gc time: 47<br> colors: cpu time: 514 real time: 530 gc time: 171</span><br>
</div><div><br></div><div>Overall, it's about 10x faster than it was originally. That's not so terrible.<br><br></div><div>Interestingly, for me at least it doesn't seem to make any difference if I create the images or not. I'm still getting the same runtime if I just call perlin/simplex 65025 times and do nothing with it. <br>
</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
(: perlin (case-> (Real -> Real)<br>
(Real Real -> Real)<br>
(Real Real Real -> Real)))<br>
<br>
Be aware that `case->' types slow down type checking. (The function<br>
body is checked once for each case.)<br></blockquote><div><br><div>After the Float/Real/Flonum changes, I ended up writing this code:<br><br><span style="font-family:courier new,monospace">(: perlin (case-> (Real -> Real)<br>
(Real Real -> Real)<br> (Real Real Real -> Real)))<br>(define (perlin x [y 0.0] [z 0.0])<br> (perlin^ (real->double-flonum x)<br> (real->double-flonum y)<br> (real->double-flonum z)))<br>
<br>(: perlin^ (Float Float Float -> Float))<br>(define (perlin^ x y z)<br> ...)</span><br></div><div><br><b>Are there any obvious pitfalls I'm missing with this approach?</b><br></div><br></div><div><b>Alternatively, when is this cost paid?</b> If it's at compile time, that's really not a big deal. If it's runtime, that's something I want to avoid.<br>
<br></div><div><b>As a side note, is it possible to type optional parameters inline?</b> It seems possible if it's both optional and a keyword, like this:<br><br><span style="font-family:courier new,monospace">(: build-perlin-image (Integer Integer [#:scale Real] -> flomap))</span><br>
<br></div><div>But not just with an optional parameter. I tried this: <br><br><span style="font-family:courier new,monospace">(: perlin (Real [Real] [Real] -> Real))</span><br></div><div><br></div><div>That doesn't work. <br>
</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* Use (exact-floor x) instead of (inexact->exact (floor x)) so TR will<br>
know that the result is an Integer. Use `fl' from `math/flonum' to<br>
keep from having to type `real->double-flonum' everywhere. Don't use<br>
`exact->inexact' in TR code. (See the `fl' docs for why not.)<br></blockquote><div><br></div><div>Another instance of not knowing that something exists. :)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* Using shadowing instead of `set!' allows Racket's JIT to generate<br>
faster code, especially when the mutated value is a flonum.<br></blockquote><div><br></div><div><b>Won't a series of defines already do this?</b> I replaced the 3 set!s in simplex with lets, but it didn't seem to actually change the runtime any. <br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Yes, do this. The only other option is examining fully expanded code in the Macro Stepper and rediscovering the Optimization Coach's advice on your own, which would be un-fun.<span class=""></span></blockquote><div><br>
</div><div>The Optimization Coach is really nice. I had to look up what the colors meant, but after that it's been most helpful.<br><br></div><div>Although there is a lot more red when using Real instead of Flonum, but the runtimes seem about the same. Is it doing more optimizations than it appears or is there still more room to eek out some additional performance? Changing Real to Float makes everything nice and green.<br>
</div></div></div></div></div></div>