Skip to content

Commit e4ff013

Browse files
committed
auto merge of #5006 : tedhorst/rust/linear_mand, r=brson
2 parents 8a520ff + 9ecb8a6 commit e4ff013

File tree

1 file changed

+44
-40
lines changed

1 file changed

+44
-40
lines changed

src/test/bench/shootout-mandelbrot.rs

+44-40
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -12,17 +12,20 @@
1212
// http://shootout.alioth.debian.org/
1313
// u64q/program.php?test=mandelbrot&lang=python3&id=2
1414
//
15-
// takes 2 optional args:
15+
// takes 3 optional args:
1616
// square image size, defaults to 80_u
1717
// output path, default is "" (no output), "-" means stdout
18+
// depth (max iterations per pixel), defaults to 50_u
1819
//
19-
// in the shootout, they use 16000 as image size
20+
// in the shootout, they use 16000 as image size, 50 as depth,
21+
// and write to stdout:
22+
//
23+
// ./shootout_mandelbrot 16000 "-" 50 > /tmp/mandel.pbm
2024
//
2125
// writes pbm image to output path
2226

23-
extern mod std;
2427
use io::WriterUtil;
25-
use std::oldmap::HashMap;
28+
use core::hashmap::linear::LinearMap;
2629

2730
struct cmplx {
2831
re: f64,
@@ -54,44 +57,43 @@ pure fn cabs(x: cmplx) -> f64
5457
x.re*x.re + x.im*x.im
5558
}
5659

57-
fn mb(x: cmplx) -> bool
60+
fn mb(x: cmplx, depth: uint) -> bool
5861
{
59-
let mut z = cmplx {re: 0f64, im: 0f64};
62+
let mut z = x;
6063
let mut i = 0;
61-
let mut in = true;
62-
while i < 50 {
63-
z = z*z + x;
64-
if cabs(z) >= 4f64 {
65-
in = false;
66-
break;
64+
while i < depth {
65+
if cabs(z) >= 4_f64 {
66+
return false;
6767
}
68+
z = z*z + x;
6869
i += 1;
6970
}
70-
in
71+
true
7172
}
7273

73-
fn fillbyte(x: cmplx, incr: f64) -> u8 {
74+
fn fillbyte(x: cmplx, incr: f64, depth: uint) -> u8 {
7475
let mut rv = 0_u8;
7576
let mut i = 0_u8;
7677
while i < 8_u8 {
7778
let z = cmplx {re: x.re + (i as f64)*incr, im: x.im};
78-
if mb(z) {
79+
if mb(z, depth) {
7980
rv += 1_u8 << (7_u8 - i);
8081
}
8182
i += 1_u8;
8283
}
8384
rv
8485
}
8586

86-
fn chanmb(i: uint, size: uint) -> Line
87+
fn chanmb(i: uint, size: uint, depth: uint) -> Line
8788
{
88-
let mut crv = ~[];
89-
let incr = 2f64/(size as f64);
90-
let y = incr*(i as f64) - 1f64;
91-
let xincr = 8f64*incr;
92-
for uint::range(0_u, size/8_u) |j| {
93-
let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y};
94-
crv.push(fillbyte(x, incr));
89+
let bsize = size/8_u;
90+
let mut crv = vec::with_capacity(bsize);
91+
let incr = 2_f64/(size as f64);
92+
let y = incr*(i as f64) - 1_f64;
93+
let xincr = 8_f64*incr;
94+
for uint::range(0_u, bsize) |j| {
95+
let x = cmplx {re: xincr*(j as f64) - 1.5_f64, im: y};
96+
crv.push(fillbyte(x, incr, depth));
9597
};
9698
Line {i:i, b:crv}
9799
}
@@ -121,34 +123,33 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
121123
~[io::Create, io::Truncate]))
122124
}
123125
};
124-
cout.write_line(~"P4");
126+
cout.write_line("P4");
125127
cout.write_line(fmt!("%u %u", size, size));
126-
let lines: HashMap<uint, ~[u8]> = HashMap();
128+
let mut lines: LinearMap<uint, Line> = LinearMap::new();
127129
let mut done = 0_u;
128130
let mut i = 0_u;
129131
while i < size {
130132
let aline = pport.recv();
131133
if aline.i == done {
132-
debug!("W %u", aline.i);
134+
debug!("W %u", done);
133135
cout.write(aline.b);
134136
done += 1_u;
135137
let mut prev = done;
136138
while prev <= i {
137-
if lines.contains_key(&prev) {
138-
debug!("WS %u", prev);
139-
cout.write(lines.get(&prev));
140-
done += 1_u;
141-
lines.remove(&prev);
142-
prev += 1_u;
143-
}
144-
else {
145-
break
146-
}
139+
match lines.pop(&prev) {
140+
Some(pl) => {
141+
debug!("WS %u", prev);
142+
cout.write(pl.b);
143+
done += 1_u;
144+
prev += 1_u;
145+
}
146+
None => break
147+
};
147148
};
148149
}
149150
else {
150151
debug!("S %u", aline.i);
151-
lines.insert(aline.i, copy aline.b); // FIXME: bad for perf
152+
lines.insert(aline.i, aline);
152153
};
153154
i += 1_u;
154155
}
@@ -157,11 +158,14 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
157158
fn main() {
158159
let args = os::args();
159160
let args = if os::getenv(~"RUST_BENCH").is_some() {
160-
~[~"", ~"4000"]
161+
~[~"", ~"4000", ~"50"]
161162
} else {
162163
args
163164
};
164165

166+
let depth = if vec::len(args) < 4_u { 50_u }
167+
else { uint::from_str(args[3]).get() };
168+
165169
let path = if vec::len(args) < 3_u { ~"" }
166170
else { copy args[2] }; // FIXME: bad for perf
167171

@@ -172,7 +176,7 @@ fn main() {
172176
let pchan = pipes::SharedChan(pchan);
173177
for uint::range(0_u, size) |j| {
174178
let cchan = pchan.clone();
175-
do task::spawn || { cchan.send(chanmb(j, size)) };
179+
do task::spawn { cchan.send(chanmb(j, size, depth)) };
176180
};
177181
writer(path, pport, size);
178182
}

0 commit comments

Comments
 (0)