perf(isFloat): cache the compiled regex instead of rebuilding it per call - #2847
Open
cesco69 wants to merge 1 commit into
Open
perf(isFloat): cache the compiled regex instead of rebuilding it per call#2847cesco69 wants to merge 1 commit into
cesco69 wants to merge 1 commit into
Conversation
…call isFloat built a new RegExp on every invocation. The pattern only varies with the decimal separator, which comes from the fixed set of locales, so the compiled regexes are now cached by separator. isInt already hoists its regexes to module scope; this brings isFloat in line. Behaviour is unchanged: the pattern is built from the same template literal, and the existing test suite passes.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2847 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 114 114
Lines 2599 2606 +7
Branches 658 659 +1
=========================================
+ Hits 2599 2606 +7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rubiin
approved these changes
Aug 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
perf(isFloat): cache the compiled regex instead of rebuilding it per call
What
isFloatbuilds aRegExpon every invocation:The pattern only varies with the decimal separator, which comes from the fixed
decimallocale table. This PR caches the compiled regexes by separator.
isInt.js, right next to it, already hoists its two regexes to module scope. This bringsisFloatin line with that.Why it matters
isFloatis not only called directly:toFloatcalls it internally too.So a caller that validates and then converts — a very common pairing — compiles the same
pattern twice per value.
Measurements
Node 26, best of 5 rounds, 500k calls per measurement, inputs
['42','3.14','-17','1e10','0','999999','-0.5','12345']:new RegExpper call)2.0x faster.
Downstream effect, measured on tsoa, which calls both
isFloatandtoFloatfor every numeric request parameter — one route with two numericparameters, per request:
That is 85% of the cost of tsoa's argument validation, removed by this one change.
Correctness
gflag, so there is nolastIndexstate to share between calls.42 -42 +42 0 3.14 -3.14 .5 5. 1e10 1E-10 '' . , - + abc 1,5 0x10 Infinity NaN '1 ' ' 1' 1.2.3 --1 1e ++ 1e+ 12345678901234567890 -0 1.0e5 .e5 +.5 -.5 e5— no divergence.npm test: 323 passing.npx eslint src/lib/isFloat.js: clean.Reproducing
bench/isfloat.mjsin this PR description's companion file, run withnode --expose-gc.