]> git.proxmox.com Git - rustc.git/blame - src/test/bench/shootout-fasta-redux.rs
Imported Upstream version 1.0.0~beta
[rustc.git] / src / test / bench / shootout-fasta-redux.rs
CommitLineData
1a4d82fc
JJ
1// The Computer Language Benchmarks Game
2// http://benchmarksgame.alioth.debian.org/
3//
4// contributed by the Rust Project Developers
5
6// Copyright (c) 2013-2014 The Rust Project Developers
7//
8// All rights reserved.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions
12// are met:
13//
14// - Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// - Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in
19// the documentation and/or other materials provided with the
20// distribution.
21//
22// - Neither the name of "The Computer Language Benchmarks Game" nor
23// the name of "The Computer Language Shootout Benchmarks" nor the
24// names of its contributors may be used to endorse or promote
25// products derived from this software without specific prior
26// written permission.
27//
28// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39// OF THE POSSIBILITY OF SUCH DAMAGE.
40
c34b1796
AL
41#![feature(core, old_io, io, core)]
42
1a4d82fc 43use std::cmp::min;
c34b1796 44use std::old_io::*;
1a4d82fc 45use std::iter::repeat;
85aaf69f 46use std::env;
1a4d82fc 47use std::slice::bytes::copy_memory;
970d7e83 48
85aaf69f
SL
49const LINE_LEN: usize = 60;
50const LOOKUP_SIZE: usize = 4 * 1024;
1a4d82fc 51const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;
970d7e83
LB
52
53// Random number generator constants
1a4d82fc
JJ
54const IM: u32 = 139968;
55const IA: u32 = 3877;
56const IC: u32 = 29573;
970d7e83 57
1a4d82fc 58const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
970d7e83
LB
59 GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
60 GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
61 AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
62 CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
63 CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
64 CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
65
1a4d82fc 66const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };
970d7e83 67
1a4d82fc 68static IUB: [AminoAcid;15] = [
970d7e83
LB
69 AminoAcid { c: 'a' as u8, p: 0.27 },
70 AminoAcid { c: 'c' as u8, p: 0.12 },
71 AminoAcid { c: 'g' as u8, p: 0.12 },
72 AminoAcid { c: 't' as u8, p: 0.27 },
73 AminoAcid { c: 'B' as u8, p: 0.02 },
74 AminoAcid { c: 'D' as u8, p: 0.02 },
75 AminoAcid { c: 'H' as u8, p: 0.02 },
76 AminoAcid { c: 'K' as u8, p: 0.02 },
77 AminoAcid { c: 'M' as u8, p: 0.02 },
78 AminoAcid { c: 'N' as u8, p: 0.02 },
79 AminoAcid { c: 'R' as u8, p: 0.02 },
80 AminoAcid { c: 'S' as u8, p: 0.02 },
81 AminoAcid { c: 'V' as u8, p: 0.02 },
82 AminoAcid { c: 'W' as u8, p: 0.02 },
83 AminoAcid { c: 'Y' as u8, p: 0.02 },
84];
85
1a4d82fc 86static HOMO_SAPIENS: [AminoAcid;4] = [
970d7e83
LB
87 AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
88 AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
89 AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
90 AminoAcid { c: 't' as u8, p: 0.3015094502008 },
91];
92
1a4d82fc
JJ
93// FIXME: Use map().
94fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
95 let mut result = Vec::new();
970d7e83 96 let mut p = 0f32;
85aaf69f 97 for a_i in a {
970d7e83
LB
98 let mut a_i = *a_i;
99 p += a_i.p;
100 a_i.p = p * LOOKUP_SCALE;
101 result.push(a_i);
102 }
1a4d82fc
JJ
103 let result_len = result.len();
104 result[result_len - 1].p = LOOKUP_SCALE;
970d7e83
LB
105 result
106}
107
c34b1796 108#[derive(Copy, Clone)]
970d7e83
LB
109struct AminoAcid {
110 c: u8,
111 p: f32,
112}
113
1a4d82fc 114struct RepeatFasta<'a, W:'a> {
970d7e83 115 alu: &'static str,
1a4d82fc 116 out: &'a mut W
970d7e83
LB
117}
118
1a4d82fc
JJ
119impl<'a, W: Writer> RepeatFasta<'a, W> {
120 fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
121 RepeatFasta { alu: alu, out: w }
970d7e83
LB
122 }
123
85aaf69f 124 fn make(&mut self, n: usize) -> IoResult<()> {
1a4d82fc 125 let alu_len = self.alu.len();
c34b1796 126 let mut buf = repeat(0).take(alu_len + LINE_LEN).collect::<Vec<_>>();
1a4d82fc
JJ
127 let alu: &[u8] = self.alu.as_bytes();
128
c34b1796 129 copy_memory(alu, &mut buf);
1a4d82fc 130 let buf_len = buf.len();
c34b1796 131 copy_memory(&alu[..LINE_LEN], &mut buf[alu_len..buf_len]);
1a4d82fc
JJ
132
133 let mut pos = 0;
134 let mut bytes;
135 let mut n = n;
136 while n > 0 {
137 bytes = min(LINE_LEN, n);
85aaf69f 138 try!(self.out.write(&buf[pos..pos + bytes]));
1a4d82fc
JJ
139 try!(self.out.write_u8('\n' as u8));
140 pos += bytes;
141 if pos > alu_len {
142 pos -= alu_len;
970d7e83 143 }
1a4d82fc 144 n -= bytes;
970d7e83 145 }
1a4d82fc 146 Ok(())
970d7e83
LB
147 }
148}
149
1a4d82fc
JJ
150fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] {
151 let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ];
152 let mut j = 0;
153 for (i, slot) in lookup.iter_mut().enumerate() {
154 while a[j].p < (i as f32) {
155 j += 1;
156 }
157 *slot = a[j];
158 }
159 lookup
160}
161
162struct RandomFasta<'a, W:'a> {
970d7e83 163 seed: u32,
1a4d82fc
JJ
164 lookup: [AminoAcid;LOOKUP_SIZE],
165 out: &'a mut W,
970d7e83
LB
166}
167
1a4d82fc
JJ
168impl<'a, W: Writer> RandomFasta<'a, W> {
169 fn new(w: &'a mut W, a: &[AminoAcid]) -> RandomFasta<'a, W> {
970d7e83
LB
170 RandomFasta {
171 seed: 42,
1a4d82fc
JJ
172 out: w,
173 lookup: make_lookup(a),
970d7e83 174 }
970d7e83
LB
175 }
176
177 fn rng(&mut self, max: f32) -> f32 {
178 self.seed = (self.seed * IA + IC) % IM;
179 max * (self.seed as f32) / (IM as f32)
180 }
181
182 fn nextc(&mut self) -> u8 {
183 let r = self.rng(1.0);
85aaf69f 184 for a in &self.lookup[..] {
970d7e83
LB
185 if a.p >= r {
186 return a.c;
187 }
188 }
189 0
190 }
191
85aaf69f 192 fn make(&mut self, n: usize) -> IoResult<()> {
1a4d82fc
JJ
193 let lines = n / LINE_LEN;
194 let chars_left = n % LINE_LEN;
195 let mut buf = [0;LINE_LEN + 1];
196
85aaf69f
SL
197 for _ in 0..lines {
198 for i in 0..LINE_LEN {
970d7e83
LB
199 buf[i] = self.nextc();
200 }
1a4d82fc
JJ
201 buf[LINE_LEN] = '\n' as u8;
202 try!(self.out.write(&buf));
203 }
85aaf69f 204 for i in 0..chars_left {
1a4d82fc 205 buf[i] = self.nextc();
970d7e83 206 }
85aaf69f 207 self.out.write(&buf[..chars_left])
970d7e83
LB
208 }
209}
210
970d7e83 211fn main() {
85aaf69f 212 let mut args = env::args();
1a4d82fc 213 let n = if args.len() > 1 {
85aaf69f 214 args.nth(1).unwrap().parse::<usize>().unwrap()
1a4d82fc
JJ
215 } else {
216 5
217 };
218
219 let mut out = stdout();
220
221 out.write_line(">ONE Homo sapiens alu").unwrap();
222 {
223 let mut repeat = RepeatFasta::new(ALU, &mut out);
224 repeat.make(n * 2).unwrap();
225 }
970d7e83 226
1a4d82fc
JJ
227 out.write_line(">TWO IUB ambiguity codes").unwrap();
228 let iub = sum_and_scale(&IUB);
85aaf69f 229 let mut random = RandomFasta::new(&mut out, &iub);
1a4d82fc 230 random.make(n * 3).unwrap();
970d7e83 231
1a4d82fc
JJ
232 random.out.write_line(">THREE Homo sapiens frequency").unwrap();
233 let homo_sapiens = sum_and_scale(&HOMO_SAPIENS);
85aaf69f 234 random.lookup = make_lookup(&homo_sapiens);
1a4d82fc 235 random.make(n * 5).unwrap();
970d7e83 236
1a4d82fc 237 random.out.write_str("\n").unwrap();
970d7e83 238}