From 477112332f930df2644fda7485cd94e6f460ca14 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Jun 2018 02:34:51 +0300 Subject: [PATCH] Optimize printing integers. GitOrigin-RevId: 4d73952b23d2f6da7cce0b21371b4d861c914b6f --- tdutils/td/utils/StringBuilder.cpp | 59 ++++++++++++++++++++++++++---- tdutils/td/utils/logging.cpp | 20 +++++----- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/tdutils/td/utils/StringBuilder.cpp b/tdutils/td/utils/StringBuilder.cpp index ce64bbc9..b0313997 100644 --- a/tdutils/td/utils/StringBuilder.cpp +++ b/tdutils/td/utils/StringBuilder.cpp @@ -10,17 +10,62 @@ #include "td/utils/port/thread_local.h" #include +#include #include #include +#include namespace td { -// TODO: optimize +template +static char *print_uint(char *current_ptr, T x) { + if (x < 100) { + if (x < 10) { + *current_ptr++ = static_cast('0' + x); + } else { + *current_ptr++ = static_cast('0' + x / 10); + *current_ptr++ = static_cast('0' + x % 10); + } + return current_ptr; + } + + auto begin_ptr = current_ptr; + do { + *current_ptr++ = static_cast('0' + x % 10); + x /= 10; + } while (x > 0); + + auto end_ptr = current_ptr - 1; + while (begin_ptr < end_ptr) { + std::swap(*begin_ptr++, *end_ptr--); + } + + return current_ptr; +} + +template +static char *print_int(char *current_ptr, T x) { + if (x < 0) { + if (x == std::numeric_limits::min()) { + std::stringstream ss; + ss << x; + auto len = narrow_cast(static_cast(ss.tellp())); + ss.read(current_ptr, len); + return current_ptr + len; + } + + *current_ptr++ = '-'; + x = -x; + } + + return print_uint(current_ptr, x); +} + StringBuilder &StringBuilder::operator<<(int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%d", x); + current_ptr_ = print_int(current_ptr_, x); return *this; } @@ -28,7 +73,7 @@ StringBuilder &StringBuilder::operator<<(unsigned int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%u", x); + current_ptr_ = print_uint(current_ptr_, x); return *this; } @@ -36,7 +81,7 @@ StringBuilder &StringBuilder::operator<<(long int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%ld", x); + current_ptr_ = print_int(current_ptr_, x); return *this; } @@ -44,7 +89,7 @@ StringBuilder &StringBuilder::operator<<(long unsigned int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%lu", x); + current_ptr_ = print_uint(current_ptr_, x); return *this; } @@ -52,7 +97,7 @@ StringBuilder &StringBuilder::operator<<(long long int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%lld", x); + current_ptr_ = print_int(current_ptr_, x); return *this; } @@ -60,7 +105,7 @@ StringBuilder &StringBuilder::operator<<(long long unsigned int x) { if (unlikely(end_ptr_ < current_ptr_)) { return on_error(); } - current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%llu", x); + current_ptr_ = print_uint(current_ptr_, x); return *this; } diff --git a/tdutils/td/utils/logging.cpp b/tdutils/td/utils/logging.cpp index 17403ff8..06059cb0 100644 --- a/tdutils/td/utils/logging.cpp +++ b/tdutils/td/utils/logging.cpp @@ -57,26 +57,26 @@ Logger::Logger(LogInterface &log, int log_level, Slice file_name, int line_num, auto thread_id = get_thread_id(); - (*this) << '['; + sb_ << '['; if (log_level < 10) { - (*this) << ' '; + sb_ << ' '; } - (*this) << log_level << "][t"; + sb_ << log_level << "][t"; if (thread_id < 10) { - (*this) << ' '; + sb_ << ' '; } - (*this) << thread_id << "][" << StringBuilder::FixedDouble(Clocks::system(), 9) << "][" << file_name << ':' - << line_num << ']'; + sb_ << thread_id << "][" << StringBuilder::FixedDouble(Clocks::system(), 9) << "][" << file_name << ':' << line_num + << ']'; if (tag_ != nullptr && *tag_) { - (*this) << "[#" << Slice(tag_) << "]"; + sb_ << "[#" << Slice(tag_) << ']'; } if (tag2_ != nullptr && *tag2_) { - (*this) << "[!" << Slice(tag2_) << "]"; + sb_ << "[!" << Slice(tag2_) << ']'; } if (!comment.empty()) { - (*this) << "[&" << comment << "]"; + sb_ << "[&" << comment << ']'; } - (*this) << "\t"; + sb_ << '\t'; } Logger::~Logger() {