Perlin vs Simplex noise performance

Initially I wanted to share here a speed comparison between SimplexNoise and Perlin noise, thinking that SimplexNoise was much faster than the standard noise(), but I realized that the main speed difference was caused by noise() being computed over 4 octaves by default when SimplexNoise does only one octave.

I used this to test performance:

import toxi.math.noise.SimplexNoise;

PApplet Perlin noise

for (int j=0; j<5; j++) {
  // measure standard noise()
  long t0 = System.nanoTime();
  float n = 0;
  for (int i=0; i<500000; i++) {
    n += noise(i * 0.01, i * 0.03);
  }
  long t1 = System.nanoTime();

  // measure SimplexNoise
  long t2 = System.nanoTime();
  n = 0;
  for (int i=0; i<500000; i++) {
    n += SimplexNoise.noise(i * 0.01, i * 0.03);
  }
  long t3 = System.nanoTime();

  println((t1 - t0)/1000000, "ms with PApplet.noise()");
  println((t3 - t2)/1000000, "ms with SimplexNoise.noise()");
  println("SimplexNoise time =", (t3-t2)/(float)(t1-t0), "% of noise time\n");
}

Which gave me results like

63 ms with PApplet.noise()
23 ms with SimplexNoise.noise()
SimplexNoise time =  0.37506297 % of noise time

48 ms with PApplet.noise()
17 ms with SimplexNoise.noise()
SimplexNoise time =  0.3666313 % of noise time

47 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.3852872 % of noise time

50 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.37369484 % of noise time

45 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.40698823 % of noise time

When I saw that I thought: wow, that’s a huge performance improvement.

But compare how each noise looks like:
2018-10-06-172008_500x500_scrot

There I realized that noise() was doing 4 octaves because of the nice small details.
If you call noiseDetail(1) you get this:
2018-10-06-171853_500x500_scrot

Generated with this program:

import toxi.math.noise.SimplexNoise;

size(500, 500);

noiseDetail(1);
float zoom = 0.03;
for(int y=0; y<height; y++) {
  for(int x=0; x<width; x++) {
    float n;
    if(x<width/2) {
      n = noise(x * zoom, y * zoom);
    } else {
      n = (float)SimplexNoise.noise(x * zoom, y * zoom);
      n = 0.5 + 0.5 * n;
    }
    stroke(n * 255);
    point(x, y);
  }
}

And in this case you can see the timing is not that different between both techniques (tiny bit faster for Simplex):

29 ms with PApplet.noise()
27 ms with SimplexNoise.noise()
SimplexNoise time =  0.9117051 % of noise time

26 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.721629 % of noise time

19 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.92072546 % of noise time

20 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.9038497 % of noise time

19 ms with PApplet.noise()
18 ms with SimplexNoise.noise()
SimplexNoise time =  0.9573687 % of noise time

At least it was an interesting find. Also, notice how Perlin noise seems to have 2 axes and low contrast while Simplex has 3 axes and higher contrast.

1 Like

Since I started comparing the two, why not continue…

Noise fields comparing both (perlin on the left, the third argument of noise is constant).
2018-10-06-174735_500x500_scrot

And same, but third argument is slowly changing time:
2018-10-06-174832_500x500_scrot

Rendered with this program:

import toxi.math.noise.SimplexNoise;

void setup() {
  size(500, 500);
  background(0);
  stroke(255, 50);
  noiseDetail(1);
}
float zoom = 0.03;
void draw() {
  float xx = random(width);
  float yy = random(height);
  for (int i=0; i<500; i++) {
    float a;
    float t = 0; // frameCount * 0.001;
    if (xx<width/2) {
      a = TWO_PI * noise(xx * zoom, yy * zoom, t);
    } else {
      a = PI * (float)(SimplexNoise.noise(xx * zoom, yy * zoom, t));
    }
    xx += cos(a);
    yy += sin(a);
    point(xx, yy);
  }
}
1 Like