[racket] Perlin and simplex noise - optimizing Racket code

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Thu Apr 11 15:39:02 EDT 2013

In functions such as

(define (mix a b t)
  (+ (* (- 1 t) a) (* t b)))

(define (fade t)
  (* t t t (+ (* t (- (* t 6) 15)) 10)))

use floating point constants:

(define (mix a b t)
  (+ (* (- 1. t) a) (* t b)))

(define (fade t)
  (* t t t (+ (* t (- (* t 6.) 15.)) 10.)))

/Jens Axel

2013/4/11 JP Verkamp <racket at jverkamp.com>

> 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
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Jens Axel Søgaard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130411/37fd906f/attachment.html>

Posted on the users mailing list.