Skip to content

Commit fade91d

Browse files
authored
repr: don't allocate while parsing floats (#5341)
parse_float32/-3.0 time: [41.721 ns 41.940 ns 42.170 ns] change: [-55.287% -55.053% -54.764%] (p = 0.00 < 0.05) Performance has improved. parse_float32/9.7 time: [41.411 ns 41.671 ns 41.918 ns] change: [-49.983% -49.783% -49.552%] (p = 0.00 < 0.05) Performance has improved. parse_float32/NaN time: [25.068 ns 25.253 ns 25.447 ns] change: [-60.892% -60.692% -60.434%] (p = 0.00 < 0.05) Performance has improved. parse_float32/inFiNiTy time: [16.827 ns 16.840 ns 16.852 ns] change: [-86.343% -86.325% -86.307%] (p = 0.00 < 0.05) Performance has improved.
1 parent 983fac6 commit fade91d

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

src/repr/benches/strconv.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,26 @@
77
// the Business Source License, use of this software will be governed
88
// by the Apache License, Version 2.0.
99

10-
use criterion::{black_box, criterion_group, criterion_main, Criterion};
10+
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
1111
use rand::rngs::StdRng;
1212
use rand::seq::SliceRandom;
1313
use rand::{Rng, SeedableRng};
1414

1515
use repr::strconv;
1616

17+
fn bench_parse_float32(c: &mut Criterion) {
18+
for s in &["-3.0", "9.7", "NaN", "inFiNiTy"] {
19+
c.bench_with_input(BenchmarkId::new("parse_float32", s), s, |b, s| {
20+
b.iter(|| strconv::parse_float32(s).unwrap())
21+
});
22+
}
23+
24+
let input = include_str!("testdata/twitter.json");
25+
c.bench_function("parse_jsonb", |b| {
26+
b.iter(|| black_box(strconv::parse_jsonb(input).unwrap()))
27+
});
28+
}
29+
1730
fn bench_parse_jsonb(c: &mut Criterion) {
1831
let input = include_str!("testdata/twitter.json");
1932
c.bench_function("parse_jsonb", |b| {
@@ -73,6 +86,7 @@ criterion_group!(
7386
benches,
7487
bench_format_list_simple,
7588
bench_format_list_nested,
89+
bench_parse_float32,
7690
bench_parse_jsonb
7791
);
7892
criterion_main!(benches);

src/repr/src/strconv.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use ore::lex::LexBuf;
3434
use serde::{Deserialize, Serialize};
3535
use uuid::Uuid;
3636

37+
use ore::ascii::UncasedStr;
3738
use ore::fmt::FormatBuffer;
3839

3940
use crate::adt::array::ArrayDimension;
@@ -126,13 +127,17 @@ where
126127

127128
/// Parses an `f32` from `s`.
128129
pub fn parse_float32(s: &str) -> Result<f32, ParseError> {
129-
match s.trim().to_lowercase().as_str() {
130-
"inf" | "infinity" | "+inf" | "+infinity" => Ok(f32::INFINITY),
131-
"-inf" | "-infinity" => Ok(f32::NEG_INFINITY),
132-
"nan" => Ok(f32::NAN),
133-
s => s
130+
let s = UncasedStr::new(s.trim());
131+
if s == "inf" || s == "infinity" || s == "+inf" || s == "+infinity" {
132+
Ok(f32::INFINITY)
133+
} else if s == "-inf" || s == "-infinity" {
134+
Ok(f32::NEG_INFINITY)
135+
} else if s == "nan" {
136+
Ok(f32::NAN)
137+
} else {
138+
s.as_str()
134139
.parse()
135-
.map_err(|e| ParseError::new("float4", s).with_details(e)),
140+
.map_err(|e| ParseError::new("float4", s.as_str()).with_details(e))
136141
}
137142
}
138143

@@ -155,13 +160,17 @@ where
155160

156161
/// Parses an `f64` from `s`.
157162
pub fn parse_float64(s: &str) -> Result<f64, ParseError> {
158-
match s.trim().to_lowercase().as_str() {
159-
"inf" | "infinity" | "+inf" | "+infinity" => Ok(f64::INFINITY),
160-
"-inf" | "-infinity" => Ok(f64::NEG_INFINITY),
161-
"nan" => Ok(f64::NAN),
162-
s => s
163+
let s = UncasedStr::new(s.trim());
164+
if s == "inf" || s == "infinity" || s == "+inf" || s == "+infinity" {
165+
Ok(f64::INFINITY)
166+
} else if s == "-inf" || s == "-infinity" {
167+
Ok(f64::NEG_INFINITY)
168+
} else if s == "nan" {
169+
Ok(f64::NAN)
170+
} else {
171+
s.as_str()
163172
.parse()
164-
.map_err(|e| ParseError::new("float8", s).with_details(e)),
173+
.map_err(|e| ParseError::new("float8", s.as_str()).with_details(e))
165174
}
166175
}
167176

0 commit comments

Comments
 (0)