Use fmt and std::from_chars to make convert integer to string and convert string to integer more efficient (#6361)

* [Optimize] optimize the speed of converting integer to string

* Use fmt and std::from_chars to make convert integer to string and convert string to integer more efficient

Co-authored-by: caiconghui <caiconghui@xiaomi.com>
This commit is contained in:
caiconghui
2021-08-04 10:55:19 +08:00
committed by GitHub
parent 16bc5fa585
commit d1007afe80
11 changed files with 71 additions and 123 deletions

View File

@ -88,7 +88,7 @@ Status FoldConstantMgr::fold_constant_expr(
result = get_result(src, ctx->root()->type().type);
}
expr_result.set_content(result);
expr_result.set_content(std::move(result));
expr_result.mutable_type()->set_type(t_type);
pexpr_result_map.mutable_map()->insert({n.first, expr_result});
@ -154,42 +154,37 @@ string FoldConstantMgr::get_result(void* src, PrimitiveType slot_type){
}
case TYPE_TINYINT: {
int8_t val = *reinterpret_cast<const int8_t*>(src);
string s;
s.push_back(val);
return s;
return fmt::format_int(val).str();
}
case TYPE_SMALLINT: {
int16_t val = *reinterpret_cast<const int16_t*>(src);
return std::to_string(val);
return fmt::format_int(val).str();
}
case TYPE_INT: {
int32_t val = *reinterpret_cast<const int32_t*>(src);
return std::to_string(val);
return fmt::format_int(val).str();
}
case TYPE_BIGINT: {
int64_t val = *reinterpret_cast<const int64_t*>(src);
return std::to_string(val);
return fmt::format_int(val).str();
}
case TYPE_LARGEINT: {
char buf[48];
int len = 48;
char* v = LargeIntValue::to_string(*reinterpret_cast<__int128*>(src), buf, &len);
return std::string(v, len);
return LargeIntValue::to_string(*reinterpret_cast<__int128*>(src));
}
case TYPE_FLOAT: {
float val = *reinterpret_cast<const float*>(src);
return std::to_string(val);
return fmt::format("{:.9g}", val);
}
case TYPE_TIME:
case TYPE_DOUBLE: {
double val = *reinterpret_cast<double*>(src);
return std::to_string(val);
return fmt::format("{:.17g}", val);
}
case TYPE_CHAR:
case TYPE_VARCHAR:
case TYPE_HLL:
case TYPE_OBJECT: {
return (reinterpret_cast<StringValue*>(src))->debug_string();
return (reinterpret_cast<StringValue*>(src))->to_string();
}
case TYPE_DATE:
case TYPE_DATETIME: {
@ -205,7 +200,6 @@ string FoldConstantMgr::get_result(void* src, PrimitiveType slot_type){
DCHECK(false) << "Type not implemented: " << slot_type;
return NULL;
}
return NULL;
}

View File

@ -26,20 +26,8 @@ namespace doris {
std::ostream& operator<<(std::ostream& os, __int128 const& value) {
std::ostream::sentry s(os);
if (s) {
unsigned __int128 tmp = value < 0 ? -value : value;
char buffer[48];
char* d = std::end(buffer);
do {
--d;
*d = "0123456789"[tmp % 10];
tmp /= 10;
} while (tmp != 0);
if (value < 0) {
--d;
*d = '-';
}
int len = std::end(buffer) - d;
if (os.rdbuf()->sputn(d, len) != len) {
std::string value_str = fmt::format("{}", value);
if (os.rdbuf()->sputn(value_str.data(), value_str.size()) != value_str.size()) {
os.setstate(std::ios_base::badbit);
}
}

View File

@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <fmt/format.h>
#include <iostream>
#include <sstream>
#include <string>
@ -36,28 +37,9 @@ const __int128 MIN_INT128 = ((__int128)0x01 << 127);
class LargeIntValue {
public:
static char* to_string(__int128 value, char* buffer, int* len) {
DCHECK(*len >= 40);
unsigned __int128 tmp = value < 0 ? -value : value;
char* d = buffer + *len;
do {
--d;
*d = "0123456789"[tmp % 10];
tmp /= 10;
} while (tmp != 0);
if (value < 0) {
--d;
*d = '-';
}
*len = (buffer + *len) - d;
return d;
}
static std::string to_string(__int128 value) {
char buf[64] = {0};
int len = 64;
char* str = to_string(value, buf, &len);
return std::string(str, len);
return fmt::format("{}", value);
}
};

View File

@ -90,11 +90,8 @@ int MysqlResultWriter::_add_row_value(int index, const TypeDescriptor& type, voi
break;
case TYPE_LARGEINT: {
char buf[48];
int len = 48;
char* v = LargeIntValue::to_string(reinterpret_cast<const PackedInt128*>(item)->value, buf,
&len);
buf_ret = _row_buffer->push_string(v, len);
auto string_value = LargeIntValue::to_string(reinterpret_cast<const PackedInt128*>(item)->value);
buf_ret = _row_buffer->push_string(string_value.data(), string_value.size());
break;
}