refactor ToExponentAndMantissa to use StrFormat instead of std::stringstream (#2138)
* perf: refactor ToExponentAndMantissa to use StrFormat instead of std::stringstream
* return pair instead of using output parameters
* Bump astral-sh/setup-uv from 7.3.0 to 7.3.1 (#2136)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/eac588ad8def6316056a12d4907a9d4d84ff7a3b...5a095e7a2014a4212f075830d4f7277575a9d098)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-version: 7.3.1
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dominic <510002+dmah42@users.noreply.github.com>
* lambda for mantissa formatting
* structured bindings and clearer code structure
* multiple fixes to avoid Windows x64 crashes (#2139)
* fix: cast size_t widths to int for variadic printer to avoid Windows x64 crashes
* extend minimum time as Windows can have a coarse timer
* vsnprintf can consume va_list so we need to copy it to avoid UB
* extend longer test runtime to other problematic tests
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
diff --git a/src/string_util.cc b/src/string_util.cc
index ae9667b..9a0d542 100644
--- a/src/string_util.cc
+++ b/src/string_util.cc
@@ -31,13 +31,15 @@
const int64_t kUnitsSize = arraysize(kBigSIUnits);
-void ToExponentAndMantissa(double val, int precision, double one_k,
- std::string* mantissa, int64_t* exponent) {
- std::stringstream mantissa_stream;
-
+std::pair<std::string, int64_t> ToExponentAndMantissa(double val, int precision,
+ double one_k) {
+ std::string mantissa;
+ int64_t exponent = 0;
if (val < 0) {
- mantissa_stream << "-";
+ mantissa = "-";
val = -val;
+ } else {
+ mantissa.clear();
}
// Adjust threshold so that it never excludes things which can't be rendered
@@ -49,41 +51,45 @@
// Values in ]simple_threshold,small_threshold[ will be printed as-is
const double simple_threshold = 0.01;
+ auto format_mantissa = [&](double v) { mantissa += StrFormat("%g", v); };
+
+ // Positive powers
if (val > big_threshold) {
- // Positive powers
double scaled = val;
for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {
scaled /= one_k;
if (scaled <= big_threshold) {
- mantissa_stream << scaled;
- *exponent = static_cast<int64_t>(i + 1);
- *mantissa = mantissa_stream.str();
- return;
+ format_mantissa(scaled);
+ exponent = static_cast<int64_t>(i + 1);
+ return std::make_pair(mantissa, exponent);
}
}
- mantissa_stream << val;
- *exponent = 0;
- } else if (val < small_threshold) {
- // Negative powers
+ format_mantissa(val);
+ exponent = 0;
+ return std::make_pair(mantissa, exponent);
+ }
+
+ // Negative powers
+ if (val < small_threshold) {
if (val < simple_threshold) {
double scaled = val;
for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {
scaled *= one_k;
if (scaled >= small_threshold) {
- mantissa_stream << scaled;
- *exponent = -static_cast<int64_t>(i + 1);
- *mantissa = mantissa_stream.str();
- return;
+ format_mantissa(scaled);
+ exponent = -static_cast<int64_t>(i + 1);
+ return std::make_pair(mantissa, exponent);
}
}
}
- mantissa_stream << val;
- *exponent = 0;
- } else {
- mantissa_stream << val;
- *exponent = 0;
+ format_mantissa(val);
+ exponent = 0;
+ return std::make_pair(mantissa, exponent);
}
- *mantissa = mantissa_stream.str();
+
+ format_mantissa(val);
+ exponent = 0;
+ return std::make_pair(mantissa, exponent);
}
std::string ExponentToPrefix(int64_t exponent, bool iec) {
@@ -104,11 +110,8 @@
std::string ToBinaryStringFullySpecified(double value, int precision,
Counter::OneK one_k) {
- std::string mantissa;
- int64_t exponent = 0;
- ToExponentAndMantissa(value, precision,
- one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa,
- &exponent);
+ auto [mantissa, exponent] = ToExponentAndMantissa(
+ value, precision, one_k == Counter::kIs1024 ? 1024.0 : 1000.0);
return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
}