Skip to content

Use std::from_chars instead of stoll/stoull in string2int.h#9007

Merged
kroening merged 1 commit into
developfrom
feature/from-chars-string2int
May 12, 2026
Merged

Use std::from_chars instead of stoll/stoull in string2int.h#9007
kroening merged 1 commit into
developfrom
feature/from-chars-string2int

Conversation

@kroening
Copy link
Copy Markdown
Collaborator

Summary

Replace the exception-based std::stoll/std::stoull implementation of string2optional<T> with std::from_chars (C++17). This removes three template functions (string2optional_base x2, wrap_string_conversion) and replaces them with a single, simpler template.

Benchmark Results

1.4M conversions (mix of valid/invalid inputs), -O2 clang++ on macOS:

Type stoll/stoull from_chars Speedup
signed long long 1424 ms 8.9 ms 161x
unsigned long long 968 ms 10.2 ms 95x
int (with narrowing) 1446 ms 7.9 ms 184x
unsigned long long (base 16) 497 ms 5.7 ms 88x

The large speedup comes from: (1) no exception throw/catch on invalid inputs, (2) no locale overhead that stoll/stoull carry.

Semantic Changes

  1. Leading whitespace: std::stoll/stoull silently skip leading whitespace; std::from_chars does not. In this codebase, inputs to string2optional are numeric literals and identifiers from the IR which never have leading whitespace, so this is not a behavioral change in practice.

  2. Overflow handling: The old code converted via long long then narrowed (throwing out_of_range on overflow, caught by wrap_string_conversion). The new code uses from_chars directly with the target type T, which returns errc::result_out_of_range. The observable behavior (returning nullopt) is identical.

  3. Partial parses: Both old and new reject strings that are not fully consumed (old via stoll semantics + narrow check, new via ptr != last check). The new version is actually stricter — stoll("123abc") would parse 123 successfully, while from_chars with the ptr != last check returns nullopt.

@kroening kroening force-pushed the feature/from-chars-string2int branch 3 times, most recently from 07849e3 to cf082cb Compare May 11, 2026 20:24
@kroening kroening changed the title Use std::from_chars instead of stoll/stoull in string2int.h Use std::from_chars instead of stoll/stoull in string2int.h May 11, 2026
@kroening kroening force-pushed the feature/from-chars-string2int branch 2 times, most recently from 53ac489 to f40c8cf Compare May 11, 2026 22:39
Replace the exception-based stoll/stoull implementation of string2optional<T>
with std::from_chars. This eliminates exception-handling overhead and locale
indirection, yielding 88-184x speedup in microbenchmarks.

Benchmark results (1.4M conversions, mix of valid/invalid inputs, -O2 clang++):

  signed long long:        stoll 1424 ms vs from_chars   8.9 ms (161x)
  unsigned long long:      stoull  968 ms vs from_chars  10.2 ms ( 95x)
  int:                     stoll 1446 ms vs from_chars   7.9 ms (184x)
  unsigned long long hex:  stoull  497 ms vs from_chars   5.7 ms ( 88x)

Semantic changes:
- Leading whitespace is no longer silently skipped. std::stoll/stoull skip
  leading whitespace; std::from_chars does not. In this codebase, inputs to
  string2optional are identifiers and numeric literals from the IR, which
  never have leading whitespace, so this is not a behavioral change in
  practice.
- The old code converted via long long then narrowed (throwing out_of_range
  on overflow). The new code uses from_chars directly with the target type,
  which returns errc::result_out_of_range on overflow. The observable
  behavior (returning nullopt on overflow) is identical.
@kroening kroening force-pushed the feature/from-chars-string2int branch from f40c8cf to 9e2a3a7 Compare May 11, 2026 23:47
@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.56%. Comparing base (166a7d4) to head (9e2a3a7).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #9007      +/-   ##
===========================================
+ Coverage    80.55%   80.56%   +0.01%     
===========================================
  Files         1707     1707              
  Lines       189016   189047      +31     
  Branches        73       73              
===========================================
+ Hits        152261   152308      +47     
+ Misses       36755    36739      -16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kroening kroening merged commit 82ba0cc into develop May 12, 2026
44 checks passed
@kroening kroening deleted the feature/from-chars-string2int branch May 12, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants