[racket] Perlin and simplex noise - optimizing Racket code

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Thu Apr 11 15:54:12 EDT 2013

At Thu, 11 Apr 2013 13:07:27 -0400,
JP Verkamp wrote:
> 
> [1  <multipart/alternative (7bit)>]
> [1.1  <text/plain; UTF-8 (7bit)>]
> Partially out of curiosity and partially in my ongoing quest to try out
> game development in Racket, I've implemented a pure Racket version each for
> Perlin and simplex noise. It's pretty much a direct translation of the code
> from this PDF, originally in C:
> http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
> 
> Here is a blog post with some pretty pictures but little actual code:
> http://blog.jverkamp.com/2013/04/11/perlin-and-simplex-noise-in-racket/
> 
> Here's just the code:
> https://github.com/jpverkamp/noise
> 
> It's definitely not pure / functional, but I think it's relatively easy to
> read (or as easy as noise functions can be).
> 
> What I'm wondering though is if someone with a bit more experience in
> optimizing Racket code could take a look at it. I know that it should be
> possible to get a bit more speed; it's almost all number crunching, mostly
> floating point math but with a few integer only bits (those are causing the
> most trouble...). At the moment, I can think of at least three routes for
> optimization although I'm probably missing something:
> 
> - using (racket/floum) -- I've tried just blindly replacing * + - / with
> fl* fl+ fl- fl/ (and fixing the numerous errors that crop up), but it
> doesn't seem to result in much of a speedup at all. I think that this is a
> combination of still requiring runtime checks on the values and having to
> convert between exact/inexact, but I'm not sure.
> 
> - using Typed Racket -- Theoretically this will allow the compiler to
> choose the correct functions as above and avoid having to do any runtime
> checks at all, although I'm not sure how much of that has been implemented.

I had a quick look at your code, and I think Typed Racket should be able
to help. The TR optimizer can specialize numeric operations, which
removes runtime checks and allows the Racket compiler to unbox
intermediate results.

To get the most of the TR optimizer, you can try the Optimization Coach
DrRacket plugin. It reports the specializations that TR is doing and
points out specialization opportunities that would require code/type
changes to be safe.

Vincent

Posted on the users mailing list.