faster float parser, added timing

This commit is contained in:
Ishan Jain 2024-01-11 03:12:13 +05:30
parent 30c779644e
commit bc9a4a739b
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27

View File

@ -1,31 +1,43 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::time::Instant;
fn main() { fn main() {
let mut file = File::open("./measurements.txt").expect("error in opening file");
let mut map = HashMap::new(); let mut map = HashMap::new();
let mut buf = Vec::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) file.read_to_end(&mut buf)
.expect("error in reading file to memory"); .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') { for line in buf.split(|&x| x == b'\n') {
let l = line.len(); let l = line.len();
if l == 0 { if l == 0 {
continue; 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 (city, val) = line.split_at(loc);
let val = &val[1..]; let val = &val[1..];
let val = String::from_utf8_lossy(val); let val = parse_float(val);
let val: f32 = val.parse().unwrap();
let (min, sum, max, counter) = let (min, sum, max, counter) =
map.entry(city) map.entry(city)
@ -37,6 +49,10 @@ fn main() {
*sum += val; *sum += val;
} }
let t2_elapsed = t2.elapsed();
let t3 = Instant::now();
let mut list: Vec<(&[u8], (f32, f32, f32, usize))> = map.into_iter().collect(); let mut list: Vec<(&[u8], (f32, f32, f32, usize))> = map.into_iter().collect();
list.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); list.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
@ -55,5 +71,41 @@ fn main() {
)); ));
} }
let t3_elapsed = t3.elapsed();
println!("{{{output}}}"); 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
} }