You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by GitBox <gi...@apache.org> on 2021/08/17 06:51:50 UTC

[GitHub] [incubator-doris] morningman commented on a change in pull request #6384: [Optimize] Speed up converting the data of other type to string in mysql_result_writer

morningman commented on a change in pull request #6384:
URL: https://github.com/apache/incubator-doris/pull/6384#discussion_r690071874



##########
File path: be/src/util/date_func.cpp
##########
@@ -55,11 +55,55 @@ uint24_t timestamp_from_date(const std::string& date_str) {
 }
 
 std::string time_str_from_double(double time) {

Review comment:
       This method seems not used?

##########
File path: be/src/runtime/decimalv2_value.cpp
##########
@@ -354,50 +354,86 @@ int DecimalV2Value::parse_from_str(const char* decimal_str, int32_t length) {
     return error;
 }
 
-std::string DecimalV2Value::to_string(int round_scale) const {
-    if (_value == 0) return std::string(1, '0');
-
-    int last_char_idx = PRECISION + 2 + (_value < 0);
-    std::string str = std::string(last_char_idx, '0');
-
-    int128_t remaining_value = _value;
-    int first_digit_idx = 0;
-    if (_value < 0) {
-        remaining_value = -_value;
-        first_digit_idx = 1;
+std::string DecimalV2Value::to_string(int scale) const {
+    int64_t int_val = int_value();
+    int32_t frac_val = abs(frac_value());
+    if (scale < 0 || scale > SCALE) {
+        if (frac_val == 0) {
+            scale = 0;
+        } else {
+            scale = SCALE;
+            while (frac_val != 0 && frac_val % 10 == 0) {
+                frac_val = frac_val / 10;
+                scale--;
+            }
+        }
+    } else {
+        frac_val = frac_val / SCALE_TRIM_ARRAY[scale];
     }
-
-    int remaining_scale = SCALE;
-    do {
-        str[--last_char_idx] = (remaining_value % 10) + '0';
-        remaining_value /= 10;
-    } while (--remaining_scale > 0);
-    str[--last_char_idx] = '.';
-
-    do {
-        str[--last_char_idx] = (remaining_value % 10) + '0';
-        remaining_value /= 10;
-        if (remaining_value == 0) {
-            if (last_char_idx > first_digit_idx) str.erase(0, last_char_idx - first_digit_idx);
-            break;
+    auto f_int = fmt::format_int(int_val);
+    if (scale == 0) {
+        return f_int.str();
+    }
+    std::string str;
+    if (_value < 0 && int_val == 0 && frac_val != 0) {
+        str.reserve(f_int.size() + scale + 2);
+        str.push_back('-');
+    } else {
+        str.reserve(f_int.size() + scale + 1);
+    }
+    str.append(f_int.data(), f_int.size());
+    str.push_back('.');
+    if (frac_val == 0) {
+        str.append(scale, '0');
+    } else {
+        auto f_frac = fmt::format_int(frac_val);
+        if (f_frac.size() < scale) {
+           str.append(scale - f_frac.size(), '0');
         }
-    } while (last_char_idx > first_digit_idx);
-
-    if (_value < 0) str[0] = '-';
+        str.append(f_frac.data(), f_frac.size());
+    }
+    return str;
+}
 
-    // right trim and round
-    int scale = 0;
-    int len = str.size();
-    for (scale = 0; scale < SCALE && scale < len; scale++) {
-        if (str[len - scale - 1] != '0') break;
+int32_t DecimalV2Value::to_buffer(char* buffer, int scale) const {

Review comment:
       This function needs to be fully tested with unit test

##########
File path: be/src/util/date_func.cpp
##########
@@ -55,11 +55,55 @@ uint24_t timestamp_from_date(const std::string& date_str) {
 }
 
 std::string time_str_from_double(double time) {
+    std::string result;
+    result.reserve(MAX_TIME_WIDTH);
     if (time < 0) {
         time = -time;
-        return fmt::format("-{:02d}:{:02d}:{:02d}", (int64_t)(time / 60 / 60), ((int64_t)(time / 60)) % 60, ((int64_t)time) % 60);
+        result.push_back('-');
     }
-    return fmt::format("{:02d}:{:02d}:{:02d}", (int64_t)(time / 60 / 60), ((int64_t)(time / 60)) % 60, ((int64_t)time) % 60);
+    int64_t hour = (int64_t)(time / 3600);
+    if (hour >= 100) {
+        auto f = fmt::format_int(hour);
+        result.append(f.data(), f.size());
+    } else {
+        result.push_back((char)('0' + (hour / 10)));
+        result.push_back((char)('0' + (hour % 10)));
+    }
+    result.push_back(':');
+    int32_t minute = ((int32_t)(time / 60)) % 60;
+    result.push_back((char)('0' + (minute / 10)));
+    result.push_back((char)('0' + (minute % 10)));
+    result.push_back(':');
+    int32_t second = ((int32_t)time) % 60;
+    result.push_back((char)('0' + (second / 10)));
+    result.push_back((char)('0' + (second % 10)));
+    return result;
+}
+
+int32_t time_to_buffer_from_double(double time, char* buffer) {

Review comment:
       need tests

##########
File path: be/test/util/CMakeLists.txt
##########
@@ -72,3 +72,7 @@ ADD_BE_TEST(s3_uri_test)
 ADD_BE_TEST(s3_storage_backend_test)
 ADD_BE_TEST(broker_storage_backend_test)
 ADD_BE_TEST(sort_heap_test)
+ADD_BE_TEST(date_func_test)
+
+target_link_libraries(Test_util Common Util Gutil ${Boost_LIBRARIES} glog gflags fmt protobuf)

Review comment:
       Why adding this? Add comment to explain.

##########
File path: fe/fe-core/src/main/java/org/apache/doris/planner/Planner.java
##########
@@ -101,9 +101,7 @@ private void setResultExprScale(Analyzer analyzer, ArrayList<Expr> outputExprs)
                             }
 
                     if (slotList.contains(slotDesc.getId()) && null != slotDesc.getColumn()) {
-                        // TODO output scale
-                        // int outputScale = slotDesc.getColumn().getType().getScale();
-                        int outputScale = 10;
+                        int outputScale = slotDesc.getColumn().getScale();

Review comment:
       Are you sure the scale is always >= 0?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org