manual number parsing

This commit is contained in:
timeshifter
2026-07-09 17:13:15 +02:00
parent 20a16fcbe2
commit be1cf6b52b
2 changed files with 44 additions and 10 deletions
+2 -1
View File
@@ -3,4 +3,5 @@
107 nightly, build-std
109 native cpu (doesn't seem to work)
95 FxHashMap
75 mmap, reduced UTF8 parsing (names)
71 mmap, reduced UTF8 parsing (names)
50 manual number parsing
+42 -9
View File
@@ -30,13 +30,12 @@ fn main() {
let mut split = line.split(|&c| c == b';');
let station = split.next().unwrap();
let parsed: f64 = String::from_utf8(split.next().unwrap().to_vec())
.unwrap()
.parse()
.unwrap();
let number = split.next().unwrap();
let parsed = parse_number(number);
// panic!();
data.entry(station)
.and_modify(|values: &mut (f64, f64, usize, f64)| {
.and_modify(|values: &mut (i64, i64, usize, i64)| {
values.0 = values.0.min(parsed);
values.1 += parsed;
values.2 += 1;
@@ -48,7 +47,7 @@ fn main() {
}
let mut stations: Vec<_> = data.keys().collect();
stations.sort();
stations.sort_unstable();
print!("{{");
@@ -60,9 +59,9 @@ fn main() {
print!(
"{s}={:.1}/{:.1}/{:.1}",
entry.0,
entry.1 / (entry.2 as f64),
entry.3
entry.0 as f64 / 10.,
(entry.1 / (entry.2 as i64)) as f64 / 10.,
entry.3 as f64 / 10.
);
if iter.peek().is_some() {
print!(", ");
@@ -70,3 +69,37 @@ fn main() {
}
println!("}}");
}
fn parse_number(number: &[u8]) -> i64 {
let sign = if *number.first().unwrap() == b'-' {
-1
} else {
1
};
let mut iter = number.iter().rev();
// 48: ASCII '0'
let mut result = (iter.next().unwrap() - 48) as i64;
iter.next(); // skip '.'
result += ((iter.next().unwrap() - 48) as i64) * 10;
if let Some(hundreds) = iter.next()
&& *hundreds != b'-'
{
result += ((hundreds - 48) as i64) * 100;
}
sign * result
}
#[cfg(test)]
mod tests {
use super::parse_number;
#[test]
fn test_parse_number() {
let input = [49, 53, 46, 51]; // "15.3"
assert_eq!(parse_number(&input), 153);
}
}