diff --git a/src/main.rs b/src/main.rs index a80dce1..19ccac7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,43 @@ use std::collections::HashMap; use std::fs::File; use std::io::Read; +use std::time::Instant; fn main() { - let mut file = File::open("./measurements.txt").expect("error in opening file"); - let mut map = HashMap::new(); - let mut buf = Vec::new(); + let t1 = Instant::now(); + + let mut file = File::open("./measurements.txt").expect("error in opening file"); + file.read_to_end(&mut buf) .expect("error in reading file to memory"); + let t1_elapsed = t1.elapsed(); + + let t2 = Instant::now(); + for line in buf.split(|&x| x == b'\n') { let l = line.len(); if l == 0 { continue; } - let loc = line.iter().position(|&x| x == b';').unwrap(); + let loc = if line[l - 4] == b';' { + l - 4 + } else if line[l - 5] == b';' { + l - 5 + } else if line[l - 6] == b';' { + l - 6 + } else { + unreachable!(); + }; let (city, val) = line.split_at(loc); let val = &val[1..]; - let val = String::from_utf8_lossy(val); - - let val: f32 = val.parse().unwrap(); + let val = parse_float(val); let (min, sum, max, counter) = map.entry(city) @@ -37,6 +49,10 @@ fn main() { *sum += val; } + let t2_elapsed = t2.elapsed(); + + let t3 = Instant::now(); + let mut list: Vec<(&[u8], (f32, f32, f32, usize))> = map.into_iter().collect(); list.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); @@ -55,5 +71,41 @@ fn main() { )); } + let t3_elapsed = t3.elapsed(); + println!("{{{output}}}"); + + eprintln!( + "read = {:?} processed = {:?} output_gen = {:?}", + t1_elapsed, t2_elapsed, t3_elapsed + ); +} + +#[inline] +fn parse_float(b: &[u8]) -> f32 { + let l = b.len(); + let mut num: i32 = 0; + let mut is_negative = false; + + for &c in b.iter().take_while(|&&x| x != b'.') { + match c { + v @ b'0'..=b'9' => { + num *= 10; + num += (v - b'0') as i32; + } + b'-' => is_negative = true, + b'.' => continue, + + _ => unreachable!(), + } + } + + let mut num = num as f32; + + num += 0.1 * (b[l - 1] - b'0') as f32; + if is_negative { + num *= -1.0; + } + + num * 10.0 / 10.0 }