[racket] Perlin and simplex noise - optimizing Racket code

From: JP Verkamp (racket at jverkamp.com)
Date: Thu Apr 11 13:07:27 EDT 2013

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.

- using the FFI to bind to a native C interface -- This would probably be
the fastest in the end, but I'd like to do as much in pure Racket as I can
for the time being (although it would be interesting to learn how to do
this). Not to mention that a part of me rejects that it wouldn't be
possible for Racket to at least match C code in a perfect world.

Right now the code takes about 1-2 seconds to generate a 256x256 image.
Optimally, that should run in near realtime, although I would be happy just
getting it into the tens or even hundreds of ms range. A part of that time
is turning the noise into a color (for testing), but even without that it
still takes about 1 second on my machine for simplex noise.

Thanks for any feedback!

JP
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130411/27a4256d/attachment.html>

Posted on the users mailing list.