1
- // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
12
12
// http://shootout.alioth.debian.org/
13
13
// u64q/program.php?test=mandelbrot&lang=python3&id=2
14
14
//
15
- // takes 3 optional args:
15
+ // takes 2 optional args:
16
16
// square image size, defaults to 80_u
17
17
// output path, default is "" (no output), "-" means stdout
18
- // depth (max iterations per pixel), defaults to 50_u
19
18
//
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
19
+ // in the shootout, they use 16000 as image size
24
20
//
25
21
// writes pbm image to output path
26
22
23
+ extern mod std;
27
24
use io:: WriterUtil ;
28
- use core :: hashmap :: linear :: LinearMap ;
25
+ use std :: oldmap :: HashMap ;
29
26
30
27
struct cmplx {
31
28
re : f64 ,
@@ -57,43 +54,44 @@ pure fn cabs(x: cmplx) -> f64
57
54
x. re * x. re + x. im * x. im
58
55
}
59
56
60
- fn mb ( x : cmplx , depth : uint ) -> bool
57
+ fn mb ( x : cmplx ) -> bool
61
58
{
62
- let mut z = x ;
59
+ let mut z = cmplx { re : 0f64 , im : 0f64 } ;
63
60
let mut i = 0 ;
64
- while i < depth {
65
- if cabs ( z) >= 4_f64 {
66
- return false ;
67
- }
61
+ let mut in = true ;
62
+ while i < 50 {
68
63
z = z* z + x;
64
+ if cabs ( z) >= 4f64 {
65
+ in = false ;
66
+ break ;
67
+ }
69
68
i += 1 ;
70
69
}
71
- true
70
+ in
72
71
}
73
72
74
- fn fillbyte ( x : cmplx , incr : f64 , depth : uint ) -> u8 {
73
+ fn fillbyte ( x : cmplx , incr : f64 ) -> u8 {
75
74
let mut rv = 0_u8 ;
76
75
let mut i = 0_u8 ;
77
76
while i < 8_u8 {
78
77
let z = cmplx { re : x. re + ( i as f64 ) * incr, im : x. im } ;
79
- if mb ( z, depth ) {
78
+ if mb ( z) {
80
79
rv += 1_u8 << ( 7_u8 - i) ;
81
80
}
82
81
i += 1_u8 ;
83
82
}
84
83
rv
85
84
}
86
85
87
- fn chanmb ( i : uint , size : uint , depth : uint ) -> Line
86
+ fn chanmb ( i : uint , size : uint ) -> Line
88
87
{
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) ) ;
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) ) ;
97
95
} ;
98
96
Line { i : i, b : crv}
99
97
}
@@ -123,33 +121,34 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
123
121
~[io::Create, io::Truncate]))
124
122
}
125
123
};
126
- cout.write_line(" P4 ") ;
124
+ cout.write_line(~ " P4 ") ;
127
125
cout. write_line ( fmt ! ( "%u %u" , size, size) ) ;
128
- let mut lines: LinearMap < uint , Line > = LinearMap :: new ( ) ;
126
+ let lines: HashMap < uint , ~ [ u8 ] > = HashMap ( ) ;
129
127
let mut done = 0_ u;
130
128
let mut i = 0_ u;
131
129
while i < size {
132
130
let aline = pport. recv ( ) ;
133
131
if aline. i == done {
134
- debug ! ( "W %u" , done ) ;
132
+ debug ! ( "W %u" , aline . i ) ;
135
133
cout. write ( aline. b ) ;
136
134
done += 1_ u;
137
135
let mut prev = done;
138
136
while prev <= i {
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
- } ;
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
+ }
148
147
} ;
149
148
}
150
149
else {
151
150
debug ! ( "S %u" , aline. i) ;
152
- lines. insert ( aline. i , aline) ;
151
+ lines. insert ( aline. i , copy aline. b ) ; // FIXME: bad for perf
153
152
} ;
154
153
i += 1_ u;
155
154
}
@@ -158,14 +157,11 @@ fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
158
157
fn main ( ) {
159
158
let args = os:: args ( ) ;
160
159
let args = if os:: getenv ( ~"RUST_BENCH ") . is_some ( ) {
161
- ~[ ~"", ~"4000 ", ~" 50 " ]
160
+ ~[ ~"", ~"4000 "]
162
161
} else {
163
162
args
164
163
} ;
165
164
166
- let depth = if vec:: len ( args) < 4_ u { 50_ u }
167
- else { uint:: from_str ( args[ 3 ] ) . get ( ) } ;
168
-
169
165
let path = if vec:: len ( args) < 3_ u { ~"" }
170
166
else { copy args[ 2 ] } ; // FIXME: bad for perf
171
167
@@ -176,7 +172,7 @@ fn main() {
176
172
let pchan = pipes:: SharedChan ( pchan) ;
177
173
for uint:: range( 0_ u, size) |j| {
178
174
let cchan = pchan. clone ( ) ;
179
- do task:: spawn { cchan. send ( chanmb ( j, size, depth ) ) } ;
175
+ do task:: spawn || { cchan. send ( chanmb ( j, size) ) } ;
180
176
} ;
181
177
writer ( path, pport, size) ;
182
178
}
0 commit comments