Skip to content

Commit bfa3e60

Browse files
committed
Clean up the Perlin noise benchmark
1 parent 92c5738 commit bfa3e60

File tree

1 file changed

+49
-65
lines changed

1 file changed

+49
-65
lines changed

src/test/bench/noise.rs

+49-65
Original file line numberDiff line numberDiff line change
@@ -8,128 +8,112 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Perlin noise benchmark from https://gist.github.com/1170424
11+
// Multi-language Perlin noise benchmark.
12+
// See https://github.com/nsf/pnoise for timings and alternative implementations.
1213

13-
use std::f64;
14-
use std::rand::Rng;
15-
use std::rand;
14+
use std::f32::consts::PI;
15+
use std::rand::{Rng, StdRng};
1616

1717
struct Vec2 {
1818
x: f32,
1919
y: f32,
2020
}
2121

22-
#[inline(always)]
2322
fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
2423

25-
#[inline(always)]
2624
fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
2725

28-
fn random_gradient<R:Rng>(r: &mut R) -> Vec2 {
29-
let v = 2.0 * f64::consts::PI * r.gen();
30-
Vec2 {
31-
x: v.cos() as f32,
32-
y: v.sin() as f32,
33-
}
26+
fn random_gradient<R: Rng>(r: &mut R) -> Vec2 {
27+
let v = PI * 2.0 * r.gen();
28+
Vec2 { x: v.cos(), y: v.sin() }
3429
}
3530

3631
fn gradient(orig: Vec2, grad: Vec2, p: Vec2) -> f32 {
37-
let sp = Vec2 {x: p.x - orig.x, y: p.y - orig.y};
38-
grad.x * sp.x + grad.y * sp.y
32+
(p.x - orig.x) * grad.x + (p.y - orig.y) * grad.y
3933
}
4034

4135
struct Noise2DContext {
4236
rgradients: [Vec2, ..256],
43-
permutations: [int, ..256],
37+
permutations: [i32, ..256],
4438
}
4539

4640
impl Noise2DContext {
47-
pub fn new() -> Noise2DContext {
48-
let mut r = rand::rng();
49-
let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ];
50-
for i in range(0, 256) {
51-
rgradients[i] = random_gradient(&mut r);
52-
}
53-
let mut permutations = [ 0, ..256 ];
54-
for i in range(0, 256) {
55-
permutations[i] = i;
41+
fn new() -> Noise2DContext {
42+
let mut rng = StdRng::new();
43+
44+
let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }, ..256];
45+
for x in rgradients.mut_iter() {
46+
*x = random_gradient(&mut rng);
5647
}
57-
r.shuffle_mut(permutations);
5848

59-
Noise2DContext {
60-
rgradients: rgradients,
61-
permutations: permutations,
49+
let mut permutations = [0i32, ..256];
50+
for (i, x) in permutations.mut_iter().enumerate() {
51+
*x = i as i32;
6252
}
53+
rng.shuffle_mut(permutations);
54+
55+
Noise2DContext { rgradients: rgradients, permutations: permutations }
6356
}
6457

65-
#[inline(always)]
66-
pub fn get_gradient(&self, x: int, y: int) -> Vec2 {
58+
fn get_gradient(&self, x: i32, y: i32) -> Vec2 {
6759
let idx = self.permutations[x & 255] + self.permutations[y & 255];
6860
self.rgradients[idx & 255]
6961
}
7062

71-
#[inline]
72-
pub fn get_gradients(&self,
73-
gradients: &mut [Vec2, ..4],
74-
origins: &mut [Vec2, ..4],
75-
x: f32,
76-
y: f32) {
63+
fn get_gradients(&self, x: f32, y: f32) -> ([Vec2, ..4], [Vec2, ..4]) {
7764
let x0f = x.floor();
7865
let y0f = y.floor();
79-
let x0 = x0f as int;
80-
let y0 = y0f as int;
66+
let x1f = x0f + 1.0;
67+
let y1f = y0f + 1.0;
68+
69+
let x0 = x0f as i32;
70+
let y0 = y0f as i32;
8171
let x1 = x0 + 1;
8272
let y1 = y0 + 1;
8373

84-
gradients[0] = self.get_gradient(x0, y0);
85-
gradients[1] = self.get_gradient(x1, y0);
86-
gradients[2] = self.get_gradient(x0, y1);
87-
gradients[3] = self.get_gradient(x1, y1);
88-
89-
origins[0] = Vec2 {x: x0f + 0.0, y: y0f + 0.0};
90-
origins[1] = Vec2 {x: x0f + 1.0, y: y0f + 0.0};
91-
origins[2] = Vec2 {x: x0f + 0.0, y: y0f + 1.0};
92-
origins[3] = Vec2 {x: x0f + 1.0, y: y0f + 1.0};
74+
([self.get_gradient(x0, y0), self.get_gradient(x1, y0),
75+
self.get_gradient(x0, y1), self.get_gradient(x1, y1)],
76+
[Vec2 { x: x0f, y: y0f }, Vec2 { x: x1f, y: y0f },
77+
Vec2 { x: x0f, y: y1f }, Vec2 { x: x1f, y: y1f }])
9378
}
9479

95-
#[inline]
96-
pub fn get(&self, x: f32, y: f32) -> f32 {
80+
fn get(&self, x: f32, y: f32) -> f32 {
9781
let p = Vec2 {x: x, y: y};
98-
let mut gradients = [ Vec2 { x: 0.0, y: 0.0 }, ..4 ];
99-
let mut origins = [ Vec2 { x: 0.0, y: 0.0 }, ..4 ];
100-
self.get_gradients(&mut gradients, &mut origins, x, y);
82+
let (gradients, origins) = self.get_gradients(x, y);
83+
10184
let v0 = gradient(origins[0], gradients[0], p);
10285
let v1 = gradient(origins[1], gradients[1], p);
10386
let v2 = gradient(origins[2], gradients[2], p);
10487
let v3 = gradient(origins[3], gradients[3], p);
88+
10589
let fx = smooth(x - origins[0].x);
10690
let vx0 = lerp(v0, v1, fx);
10791
let vx1 = lerp(v2, v3, fx);
10892
let fy = smooth(y - origins[0].y);
93+
10994
lerp(vx0, vx1, fy)
11095
}
11196
}
11297

11398
fn main() {
114-
let symbols = [" ", "░", "▒", "▓", "█", "█"];
99+
let symbols = [' ', '░', '▒', '▓', '█', '█'];
115100
let mut pixels = [0f32, ..256*256];
116-
let n2d = ~Noise2DContext::new();
117-
for _ in range(0, 100u) {
101+
let n2d = Noise2DContext::new();
102+
103+
for _ in range(0, 100) {
118104
for y in range(0, 256) {
119105
for x in range(0, 256) {
120-
let v = n2d.get(
121-
x as f32 * 0.1f32,
122-
y as f32 * 0.1f32
123-
) * 0.5f32 + 0.5f32;
124-
pixels[y*256+x] = v;
125-
};
126-
};
127-
};
106+
let v = n2d.get(x as f32 * 0.1, y as f32 * 0.1);
107+
pixels[y*256+x] = v * 0.5 + 0.5;
108+
}
109+
}
110+
}
128111

129112
for y in range(0, 256) {
130113
for x in range(0, 256) {
131-
print!("{}", symbols[(pixels[y*256+x] / 0.2f32) as int]);
114+
let idx = (pixels[y*256+x] / 0.2) as uint;
115+
print!("{:c}", symbols[idx]);
132116
}
133-
println!("");
117+
print!("\n");
134118
}
135119
}

0 commit comments

Comments
 (0)