Optimize `numberToString()`
This function is slower than it needs to be due to the expensive inserts at the front of the string. The new version is 38 times faster for a 9-digit number using GCC 13.2 with full optimizations according to Quick Bench.
This commit is contained in:
parent
a337452179
commit
d8e144d312
|
@ -421,13 +421,15 @@ template <typename IntegralType, class StringType = std::string, typename BaseTy
|
||||||
CppUtilities::Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
|
CppUtilities::Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * = nullptr>
|
||||||
StringType numberToString(IntegralType number, BaseType base = 10)
|
StringType numberToString(IntegralType number, BaseType base = 10)
|
||||||
{
|
{
|
||||||
std::size_t resSize = 0;
|
auto resSize = std::size_t();
|
||||||
for (auto n = number; n; n /= static_cast<IntegralType>(base), ++resSize)
|
auto n = number;
|
||||||
;
|
|
||||||
StringType res;
|
|
||||||
res.reserve(resSize);
|
|
||||||
do {
|
do {
|
||||||
res.insert(res.begin(), digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % base)));
|
n /= static_cast<IntegralType>(base), ++resSize;
|
||||||
|
} while (n);
|
||||||
|
auto res = StringType(resSize, typename StringType::value_type());
|
||||||
|
auto resIter = res.end();
|
||||||
|
do {
|
||||||
|
*(--resIter) = digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % static_cast<IntegralType>(base)));
|
||||||
number /= static_cast<IntegralType>(base);
|
number /= static_cast<IntegralType>(base);
|
||||||
} while (number);
|
} while (number);
|
||||||
return res;
|
return res;
|
||||||
|
@ -443,24 +445,23 @@ template <typename IntegralType, class StringType = std::string, typename BaseTy
|
||||||
Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * = nullptr>
|
Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * = nullptr>
|
||||||
StringType numberToString(IntegralType number, BaseType base = 10)
|
StringType numberToString(IntegralType number, BaseType base = 10)
|
||||||
{
|
{
|
||||||
const bool negative = number < 0;
|
const auto negative = number < 0;
|
||||||
std::size_t resSize;
|
auto resSize = std::size_t();
|
||||||
if (negative) {
|
if (negative) {
|
||||||
number = -number, resSize = 1;
|
number = -number, resSize = 1;
|
||||||
} else {
|
|
||||||
resSize = 0;
|
|
||||||
}
|
}
|
||||||
for (auto n = number; n; n /= static_cast<IntegralType>(base), ++resSize)
|
auto n = number;
|
||||||
;
|
|
||||||
StringType res;
|
|
||||||
res.reserve(resSize);
|
|
||||||
do {
|
do {
|
||||||
res.insert(res.begin(),
|
n /= static_cast<IntegralType>(base), ++resSize;
|
||||||
digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % static_cast<IntegralType>(base))));
|
} while (n);
|
||||||
|
auto res = StringType(resSize, typename StringType::value_type());
|
||||||
|
auto resIter = res.end();
|
||||||
|
do {
|
||||||
|
*(--resIter) = digitToChar<typename StringType::value_type>(static_cast<typename StringType::value_type>(number % static_cast<IntegralType>(base)));
|
||||||
number /= static_cast<IntegralType>(base);
|
number /= static_cast<IntegralType>(base);
|
||||||
} while (number);
|
} while (number);
|
||||||
if (negative) {
|
if (negative) {
|
||||||
res.insert(res.begin(), '-');
|
*(--resIter) = '-';
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue