about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-02-19 14:58:30 -0800
committerbors <bors@rust-lang.org>2013-02-19 14:58:30 -0800
commite4ff01317c3502efae7d99bc4ed6646ad53745f5 (patch)
treecb22643ce98fc5d5cc56862085c9863a446e7ad3 /src
parent8a520ff99fb2fe8e289d940dde27b7df645d6b3a (diff)
parent9ecb8a60ed9737351846eb875107ab3680e9ebd8 (diff)
downloadrust-e4ff01317c3502efae7d99bc4ed6646ad53745f5.tar.gz
rust-e4ff01317c3502efae7d99bc4ed6646ad53745f5.zip
auto merge of #5006 : tedhorst/rust/linear_mand, r=brson
Diffstat (limited to 'src')
-rw-r--r--src/test/bench/shootout-mandelbrot.rs84
1 files changed, 44 insertions, 40 deletions
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index 5ab9b068d0b..840cec44c64 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -12,17 +12,20 @@
 //  http://shootout.alioth.debian.org/
 //   u64q/program.php?test=mandelbrot&lang=python3&id=2
 //
-//  takes 2 optional args:
+//  takes 3 optional args:
 //   square image size, defaults to 80_u
 //   output path, default is "" (no output), "-" means stdout
+//   depth (max iterations per pixel), defaults to 50_u
 //
-//  in the shootout, they use 16000 as image size
+//  in the shootout, they use 16000 as image size, 50 as depth,
+//   and write to stdout:
+//
+//  ./shootout_mandelbrot 16000 "-" 50 > /tmp/mandel.pbm
 //
 //  writes pbm image to output path
 
-extern mod std;
 use io::WriterUtil;
-use std::oldmap::HashMap;
+use core::hashmap::linear::LinearMap;
 
 struct cmplx {
     re: f64,
@@ -54,28 +57,26 @@ pure fn cabs(x: cmplx) -> f64
     x.re*x.re + x.im*x.im
 }
 
-fn mb(x: cmplx) -> bool
+fn mb(x: cmplx, depth: uint) -> bool
 {
-    let mut z = cmplx {re: 0f64, im: 0f64};
+    let mut z = x;
     let mut i = 0;
-    let mut in = true;
-    while i < 50 {
-        z = z*z + x;
-        if cabs(z) >= 4f64 {
-            in = false;
-            break;
+    while i < depth {
+        if cabs(z) >= 4_f64 {
+            return false;
         }
+        z = z*z + x;
         i += 1;
     }
-    in
+    true
 }
 
-fn fillbyte(x: cmplx, incr: f64) -> u8 {
+fn fillbyte(x: cmplx, incr: f64, depth: uint) -> u8 {
     let mut rv = 0_u8;
     let mut i = 0_u8;
     while i < 8_u8 {
         let z = cmplx {re: x.re + (i as f64)*incr, im: x.im};
-        if mb(z) {
+        if mb(z, depth) {
             rv += 1_u8 << (7_u8 - i);
         }
         i += 1_u8;
@@ -83,15 +84,16 @@ fn fillbyte(x: cmplx, incr: f64) -> u8 {
     rv
 }
 
-fn chanmb(i: uint, size: uint) -> Line
+fn chanmb(i: uint, size: uint, depth: uint) -> Line
 {
-    let mut crv = ~[];
-    let incr = 2f64/(size as f64);
-    let y = incr*(i as f64) - 1f64;
-    let xincr = 8f64*incr;
-    for uint::range(0_u, size/8_u) |j| {
-        let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y};
-        crv.push(fillbyte(x, incr));
+    let bsize = size/8_u;
+    let mut crv = vec::with_capacity(bsize);
+    let incr = 2_f64/(size as f64);
+    let y = incr*(i as f64) - 1_f64;
+    let xincr = 8_f64*incr;
+    for uint::range(0_u, bsize) |j| {
+        let x = cmplx {re: xincr*(j as f64) - 1.5_f64, im: y};
+        crv.push(fillbyte(x, incr, depth));
     };
     Line {i:i, b:crv}
 }
@@ -121,34 +123,33 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
                 ~[io::Create, io::Truncate]))
         }
     };
-    cout.write_line(~"P4");
+    cout.write_line("P4");
     cout.write_line(fmt!("%u %u", size, size));
-    let lines: HashMap<uint, ~[u8]> = HashMap();
+    let mut lines: LinearMap<uint, Line> = LinearMap::new();
     let mut done = 0_u;
     let mut i = 0_u;
     while i < size {
         let aline = pport.recv();
         if aline.i == done {
-            debug!("W %u", aline.i);
+            debug!("W %u", done);
             cout.write(aline.b);
             done += 1_u;
             let mut prev = done;
             while prev <= i {
-                if lines.contains_key(&prev) {
-                    debug!("WS %u", prev);
-                    cout.write(lines.get(&prev));
-                    done += 1_u;
-                    lines.remove(&prev);
-                    prev += 1_u;
-                }
-                else {
-                    break
-                }
+                match lines.pop(&prev) {
+                    Some(pl) => {
+                        debug!("WS %u", prev);
+                        cout.write(pl.b);
+                        done += 1_u;
+                        prev += 1_u;
+                    }
+                    None => break
+                };
             };
         }
         else {
             debug!("S %u", aline.i);
-            lines.insert(aline.i, copy aline.b);    // FIXME: bad for perf
+            lines.insert(aline.i, aline);
         };
         i += 1_u;
     }
@@ -157,11 +158,14 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
 fn main() {
     let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
-        ~[~"", ~"4000"]
+        ~[~"", ~"4000", ~"50"]
     } else {
         args
     };
 
+    let depth = if vec::len(args) < 4_u { 50_u }
+    else { uint::from_str(args[3]).get() };
+
     let path = if vec::len(args) < 3_u { ~"" }
     else { copy args[2] };  // FIXME: bad for perf
 
@@ -172,7 +176,7 @@ fn main() {
     let pchan = pipes::SharedChan(pchan);
     for uint::range(0_u, size) |j| {
         let cchan = pchan.clone();
-        do task::spawn || { cchan.send(chanmb(j, size)) };
+        do task::spawn { cchan.send(chanmb(j, size, depth)) };
     };
     writer(path, pport, size);
 }