Branchless temperature parsing
This commit is contained in:
parent
9d597c8e39
commit
e934cec398
1 changed files with 17 additions and 21 deletions
|
@ -116,15 +116,12 @@ pub(crate) fn run(args: Args) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_temp(temp: &[u8]) -> i64 {
|
fn parse_temp(input: &[u8], sep_pos: usize, nl_pos: usize) -> i64 {
|
||||||
let dec = |b| (b - b'0') as i64;
|
let sign = 2 * (unsafe { *input.get_unchecked(sep_pos + 1) } != b'-') as i64 - 1;
|
||||||
let (sign, a, b, c) = match temp {
|
let a_byte = unsafe { *input.get_unchecked(nl_pos - 4) };
|
||||||
[b'-', a, b, b'.', c] => (-1, dec(a), dec(b), dec(c)),
|
let a = (b'0' <= a_byte && a_byte <= b'9') as i64 * a_byte.wrapping_sub(b'0') as i64;
|
||||||
[b'-', b, b'.', c] => (-1, 0, dec(b), dec(c)),
|
let b = (unsafe { *input.get_unchecked(nl_pos - 3) } - b'0') as i64;
|
||||||
[a, b, b'.', c] => (1, dec(a), dec(b), dec(c)),
|
let c = (unsafe { *input.get_unchecked(nl_pos - 1) } - b'0') as i64;
|
||||||
[b, b'.', c] => (1, 0, dec(b), dec(c)),
|
|
||||||
_ => panic!("bad input"),
|
|
||||||
};
|
|
||||||
sign * (a * 100 + b * 10 + c)
|
sign * (a * 100 + b * 10 + c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,16 +131,15 @@ fn chunk(input: &[u8], pb: ProgressBar) -> Result<HashMap<&[u8], Data>> {
|
||||||
let mut start = 0;
|
let mut start = 0;
|
||||||
let mut last_pb_update: usize = 0;
|
let mut last_pb_update: usize = 0;
|
||||||
let mut iter = memchr2_iter(b'\n', b';', input);
|
let mut iter = memchr2_iter(b'\n', b';', input);
|
||||||
while let Some(split) = iter.next() {
|
while let Some(sep_pos) = iter.next() {
|
||||||
if input[split] != b';' {
|
if unsafe { *input.get_unchecked(sep_pos) } != b';' {
|
||||||
start = split + 1;
|
start = sep_pos + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let pos = iter.next().context("bad input")?;
|
let nl_pos = unsafe { iter.next().unwrap_unchecked() };
|
||||||
let city = &input[start..split];
|
let city = unsafe { input.get_unchecked(start..sep_pos) };
|
||||||
let temperature = &input[split + 1..pos];
|
let temperature = parse_temp(input, sep_pos, nl_pos);
|
||||||
start = pos + 1;
|
start = nl_pos + 1;
|
||||||
let temperature = parse_temp(temperature);
|
|
||||||
let entry = data.entry(city);
|
let entry = data.entry(city);
|
||||||
entry
|
entry
|
||||||
.and_modify(|data| {
|
.and_modify(|data| {
|
||||||
|
@ -158,12 +154,12 @@ fn chunk(input: &[u8], pb: ProgressBar) -> Result<HashMap<&[u8], Data>> {
|
||||||
sum: temperature,
|
sum: temperature,
|
||||||
count: 1,
|
count: 1,
|
||||||
});
|
});
|
||||||
let last_pb_update_delta = pos - last_pb_update;
|
let last_pb_update_delta = nl_pos - last_pb_update;
|
||||||
if last_pb_update_delta >= 10_000_000 {
|
if last_pb_update_delta >= 10_000_000 {
|
||||||
pb.inc(last_pb_update_delta.try_into()?);
|
pb.inc(last_pb_update_delta as u64);
|
||||||
last_pb_update = pos;
|
last_pb_update = nl_pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pb.inc((input.len() - last_pb_update).try_into()?);
|
pb.inc((input.len() - last_pb_update) as u64);
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue