Skip to content

Performance cliff when parsing f64 above 1e305 #53015

Closed

Description

I noticed the following performance cliff of 3 orders of magnitude:

#![feature(test)]

#[cfg(test)]
extern crate test;

#[bench]
fn bench_parse_1e304(b: &mut test::Bencher) {
    // Anything under 1e305 is reasonably fast: ~120 ns/iter
    b.iter(|| "1.234e304".parse::<f64>());
}

#[bench]
fn bench_parse_1e305(b: &mut test::Bencher) {
    // Anything 1e305 or above is slower by 3 orders of magnitude: ~220,000 ns/iter 
    b.iter(|| "1.234e305".parse::<f64>());
}

Playground that reproduces the same behavior.

I tried Go and it parses both inputs in 60 ns. The resulting bits are the same in both implementations.

package test

import (
	"strconv"
	"testing"
)

func BenchmarkFast(b *testing.B) {
	for n := 0; n < b.N; n++ {
		strconv.ParseFloat("1.234e304", 64)
	}
}

func BenchmarkAlsoFast(b *testing.B) {
	for n := 0; n < b.N; n++ {
		strconv.ParseFloat("1.234e305", 64)
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-slowIssue: Problems and improvements with respect to performance of generated code.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions