Skip to content

Commit

Permalink
repr: don't allocate while parsing floats (#5341)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
benesch authored Jan 15, 2021
1 parent 983fac6 commit fade91d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
16 changes: 15 additions & 1 deletion src/repr/benches/strconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,26 @@
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use rand::rngs::StdRng;
use rand::seq::SliceRandom;
use rand::{Rng, SeedableRng};

use repr::strconv;

fn bench_parse_float32(c: &mut Criterion) {
for s in &["-3.0", "9.7", "NaN", "inFiNiTy"] {
c.bench_with_input(BenchmarkId::new("parse_float32", s), s, |b, s| {
b.iter(|| strconv::parse_float32(s).unwrap())
});
}

let input = include_str!("testdata/twitter.json");
c.bench_function("parse_jsonb", |b| {
b.iter(|| black_box(strconv::parse_jsonb(input).unwrap()))
});
}

fn bench_parse_jsonb(c: &mut Criterion) {
let input = include_str!("testdata/twitter.json");
c.bench_function("parse_jsonb", |b| {
Expand Down Expand Up @@ -73,6 +86,7 @@ criterion_group!(
benches,
bench_format_list_simple,
bench_format_list_nested,
bench_parse_float32,
bench_parse_jsonb
);
criterion_main!(benches);
33 changes: 21 additions & 12 deletions src/repr/src/strconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use ore::lex::LexBuf;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use ore::ascii::UncasedStr;
use ore::fmt::FormatBuffer;

use crate::adt::array::ArrayDimension;
Expand Down Expand Up @@ -126,13 +127,17 @@ where

/// Parses an `f32` from `s`.
pub fn parse_float32(s: &str) -> Result<f32, ParseError> {
match s.trim().to_lowercase().as_str() {
"inf" | "infinity" | "+inf" | "+infinity" => Ok(f32::INFINITY),
"-inf" | "-infinity" => Ok(f32::NEG_INFINITY),
"nan" => Ok(f32::NAN),
s => s
let s = UncasedStr::new(s.trim());
if s == "inf" || s == "infinity" || s == "+inf" || s == "+infinity" {
Ok(f32::INFINITY)
} else if s == "-inf" || s == "-infinity" {
Ok(f32::NEG_INFINITY)
} else if s == "nan" {
Ok(f32::NAN)
} else {
s.as_str()
.parse()
.map_err(|e| ParseError::new("float4", s).with_details(e)),
.map_err(|e| ParseError::new("float4", s.as_str()).with_details(e))
}
}

Expand All @@ -155,13 +160,17 @@ where

/// Parses an `f64` from `s`.
pub fn parse_float64(s: &str) -> Result<f64, ParseError> {
match s.trim().to_lowercase().as_str() {
"inf" | "infinity" | "+inf" | "+infinity" => Ok(f64::INFINITY),
"-inf" | "-infinity" => Ok(f64::NEG_INFINITY),
"nan" => Ok(f64::NAN),
s => s
let s = UncasedStr::new(s.trim());
if s == "inf" || s == "infinity" || s == "+inf" || s == "+infinity" {
Ok(f64::INFINITY)
} else if s == "-inf" || s == "-infinity" {
Ok(f64::NEG_INFINITY)
} else if s == "nan" {
Ok(f64::NAN)
} else {
s.as_str()
.parse()
.map_err(|e| ParseError::new("float8", s).with_details(e)),
.map_err(|e| ParseError::new("float8", s.as_str()).with_details(e))
}
}

Expand Down

0 comments on commit fade91d

Please sign in to comment.