]> git.lizzy.rs Git - rust.git/blob - src/test/bench/shootout-fasta.rs
auto merge of #17341 : alexcrichton/rust/unignore, r=brson
[rust.git] / src / test / bench / shootout-fasta.rs
1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
3 //
4 // contributed by the Rust Project Developers
5
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::io;
42 use std::io::{BufferedWriter, File};
43 use std::cmp::min;
44 use std::os;
45
46 static LINE_LENGTH: uint = 60;
47 static IM: u32 = 139968;
48
49 struct MyRandom {
50     last: u32
51 }
52 impl MyRandom {
53     fn new() -> MyRandom { MyRandom { last: 42 } }
54     fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32}
55     fn gen(&mut self) -> u32 {
56         self.last = (self.last * 3877 + 29573) % IM;
57         self.last
58     }
59 }
60
61 struct AAGen<'a> {
62     rng: &'a mut MyRandom,
63     data: Vec<(u32, u8)>
64 }
65 impl<'a> AAGen<'a> {
66     fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> {
67         let mut cum = 0.;
68         let data = aa.iter()
69             .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) })
70             .collect();
71         AAGen { rng: rng, data: data }
72     }
73 }
74 impl<'a> Iterator<u8> for AAGen<'a> {
75     fn next(&mut self) -> Option<u8> {
76         let r = self.rng.gen();
77         self.data.iter()
78             .skip_while(|pc| pc.val0() < r)
79             .map(|&(_, c)| c)
80             .next()
81     }
82 }
83
84 fn make_fasta<W: Writer, I: Iterator<u8>>(
85     wr: &mut W, header: &str, mut it: I, mut n: uint)
86 {
87     wr.write(header.as_bytes());
88     let mut line = [0u8, .. LINE_LENGTH + 1];
89     while n > 0 {
90         let nb = min(LINE_LENGTH, n);
91         for i in range(0, nb) {
92             line[i] = it.next().unwrap();
93         }
94         n -= nb;
95         line[nb] = '\n' as u8;
96         wr.write(line.slice_to(nb + 1));
97     }
98 }
99
100 fn run<W: Writer>(writer: &mut W) {
101     let args = os::args();
102     let args = args.as_slice();
103     let n = if os::getenv("RUST_BENCH").is_some() {
104         25000000
105     } else if args.len() <= 1u {
106         1000
107     } else {
108         from_str(args[1].as_slice()).unwrap()
109     };
110
111     let rng = &mut MyRandom::new();
112     let alu =
113         "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
114         GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
115         CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
116         ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
117         GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
118         AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
119         AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
120     let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12),
121                 ('t', 0.27), ('B', 0.02), ('D', 0.02),
122                 ('H', 0.02), ('K', 0.02), ('M', 0.02),
123                 ('N', 0.02), ('R', 0.02), ('S', 0.02),
124                 ('V', 0.02), ('W', 0.02), ('Y', 0.02)];
125     let homosapiens = &[('a', 0.3029549426680),
126                         ('c', 0.1979883004921),
127                         ('g', 0.1975473066391),
128                         ('t', 0.3015094502008)];
129
130     make_fasta(writer, ">ONE Homo sapiens alu\n",
131                alu.as_bytes().iter().cycle().map(|c| *c), n * 2);
132     make_fasta(writer, ">TWO IUB ambiguity codes\n",
133                AAGen::new(rng, iub), n * 3);
134     make_fasta(writer, ">THREE Homo sapiens frequency\n",
135                AAGen::new(rng, homosapiens), n * 5);
136
137     writer.flush();
138 }
139
140 fn main() {
141     if os::getenv("RUST_BENCH").is_some() {
142         let mut file = BufferedWriter::new(File::create(&Path::new("./shootout-fasta.data")));
143         run(&mut file);
144     } else {
145         run(&mut io::stdout());
146     }
147 }