]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // The Computer Language Benchmarks Game |
2 | // http://benchmarksgame.alioth.debian.org/ | |
223e47cc | 3 | // |
1a4d82fc | 4 | // contributed by the Rust Project Developers |
223e47cc | 5 | |
1a4d82fc JJ |
6 | // Copyright (c) 2012-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 | ||
41 | use std::cmp::min; | |
85aaf69f | 42 | use std::env; |
9346a6ac AL |
43 | use std::fs::File; |
44 | use std::io::{self, BufWriter}; | |
45 | use std::io::prelude::*; | |
970d7e83 | 46 | |
85aaf69f | 47 | const LINE_LENGTH: usize = 60; |
1a4d82fc | 48 | const IM: u32 = 139968; |
223e47cc LB |
49 | |
50 | struct MyRandom { | |
51 | last: u32 | |
52 | } | |
1a4d82fc JJ |
53 | impl MyRandom { |
54 | fn new() -> MyRandom { MyRandom { last: 42 } } | |
55 | fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32} | |
56 | fn gen(&mut self) -> u32 { | |
57 | self.last = (self.last * 3877 + 29573) % IM; | |
58 | self.last | |
223e47cc | 59 | } |
223e47cc LB |
60 | } |
61 | ||
1a4d82fc JJ |
62 | struct AAGen<'a> { |
63 | rng: &'a mut MyRandom, | |
64 | data: Vec<(u32, u8)> | |
65 | } | |
66 | impl<'a> AAGen<'a> { | |
67 | fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> { | |
68 | let mut cum = 0.; | |
69 | let data = aa.iter() | |
70 | .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) }) | |
71 | .collect(); | |
72 | AAGen { rng: rng, data: data } | |
223e47cc | 73 | } |
223e47cc | 74 | } |
1a4d82fc JJ |
75 | impl<'a> Iterator for AAGen<'a> { |
76 | type Item = u8; | |
77 | ||
78 | fn next(&mut self) -> Option<u8> { | |
79 | let r = self.rng.gen(); | |
80 | self.data.iter() | |
81 | .skip_while(|pc| pc.0 < r) | |
82 | .map(|&(_, c)| c) | |
83 | .next() | |
223e47cc | 84 | } |
223e47cc LB |
85 | } |
86 | ||
9346a6ac | 87 | fn make_fasta<W: Write, I: Iterator<Item=u8>>( |
85aaf69f | 88 | wr: &mut W, header: &str, mut it: I, mut n: usize) |
9346a6ac | 89 | -> io::Result<()> |
1a4d82fc JJ |
90 | { |
91 | try!(wr.write(header.as_bytes())); | |
c34b1796 | 92 | let mut line = [0; LINE_LENGTH + 1]; |
1a4d82fc JJ |
93 | while n > 0 { |
94 | let nb = min(LINE_LENGTH, n); | |
85aaf69f | 95 | for i in 0..nb { |
1a4d82fc | 96 | line[i] = it.next().unwrap(); |
223e47cc | 97 | } |
1a4d82fc JJ |
98 | n -= nb; |
99 | line[nb] = '\n' as u8; | |
85aaf69f | 100 | try!(wr.write(&line[..nb+1])); |
970d7e83 | 101 | } |
1a4d82fc | 102 | Ok(()) |
223e47cc LB |
103 | } |
104 | ||
9346a6ac | 105 | fn run<W: Write>(writer: &mut W) -> io::Result<()> { |
85aaf69f SL |
106 | let mut args = env::args(); |
107 | let n = if env::var_os("RUST_BENCH").is_some() { | |
1a4d82fc | 108 | 25000000 |
85aaf69f | 109 | } else if args.len() <= 1 { |
1a4d82fc | 110 | 1000 |
223e47cc | 111 | } else { |
85aaf69f | 112 | args.nth(1).unwrap().parse().unwrap() |
223e47cc LB |
113 | }; |
114 | ||
1a4d82fc JJ |
115 | let rng = &mut MyRandom::new(); |
116 | let alu = | |
117 | "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\ | |
118 | GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\ | |
119 | CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\ | |
120 | ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\ | |
121 | GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\ | |
122 | AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\ | |
123 | AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"; | |
124 | let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12), | |
125 | ('t', 0.27), ('B', 0.02), ('D', 0.02), | |
126 | ('H', 0.02), ('K', 0.02), ('M', 0.02), | |
127 | ('N', 0.02), ('R', 0.02), ('S', 0.02), | |
128 | ('V', 0.02), ('W', 0.02), ('Y', 0.02)]; | |
129 | let homosapiens = &[('a', 0.3029549426680), | |
130 | ('c', 0.1979883004921), | |
131 | ('g', 0.1975473066391), | |
132 | ('t', 0.3015094502008)]; | |
133 | ||
134 | try!(make_fasta(writer, ">ONE Homo sapiens alu\n", | |
85aaf69f | 135 | alu.as_bytes().iter().cycle().cloned(), n * 2)); |
1a4d82fc JJ |
136 | try!(make_fasta(writer, ">TWO IUB ambiguity codes\n", |
137 | AAGen::new(rng, iub), n * 3)); | |
138 | try!(make_fasta(writer, ">THREE Homo sapiens frequency\n", | |
139 | AAGen::new(rng, homosapiens), n * 5)); | |
140 | ||
141 | writer.flush() | |
142 | } | |
143 | ||
144 | fn main() { | |
85aaf69f | 145 | let res = if env::var_os("RUST_BENCH").is_some() { |
9346a6ac | 146 | let mut file = BufWriter::new(File::create("./shootout-fasta.data").unwrap()); |
1a4d82fc | 147 | run(&mut file) |
223e47cc | 148 | } else { |
9346a6ac | 149 | run(&mut io::stdout()) |
223e47cc | 150 | }; |
1a4d82fc | 151 | res.unwrap() |
223e47cc | 152 | } |