Skip to content

Fast path for parsing decimal literals #3288

@overlookmotel

Description

@overlookmotel

#3283 made an optimization to the parser to avoid checking for _s in numeric literals twice, and got a nice 1% speed-up on parser benchmarks.

It occurs to me that we could repeat the trick for the common case of simple decimal literals (e.g. 0, 1, 123). str::parse::<f64>() is quite a complicated function which checks for all kinds of things (exponent, decimal point, valid input etc). All of this is repeated work, since we've already determined in the lexer what the input is.

Perhaps we could have a flag which lexer sets if the input is a simple case, and then use a hand-rolled parse_simple_decimal function to convert to f64, like the ones we have for binary and octal?

fn parse_octal(s: &str) -> f64 {
debug_assert!(!s.is_empty());
let mut result = 0_f64;
for c in s.as_bytes().iter().filter(|s| s != &&b'_') {
#[allow(clippy::cast_lossless)]
let value = (c - b'0') as f64;
result = result.mul_add(8.0, value);
}
result
}

(we should base implementation on std's str::parse::<f64> as it's probably very optimized already, but just cut out all the extraneous checks)

Given that #3283 got a 1% speed-up, maybe this can get the same again, or maybe more?

@DonIsaac Would you be interested in investigating?

Metadata

Metadata

Assignees

Labels

A-parserArea - ParserC-performanceCategory - Solution not expected to change functional behavior, only performance

Type

No type

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions