This is an automated email from the ASF dual-hosted git repository.

gabriellee pushed a commit to branch opt_perf
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/opt_perf by this push:
     new 677b837a15 [Improvement](string) Optimize scanning for string (#12909)
677b837a15 is described below

commit 677b837a15d55e51424f3d12d0b3edb9cd00cc5d
Author: Gabriel <gabrielleeb...@gmail.com>
AuthorDate: Fri Sep 23 17:44:48 2022 +0800

    [Improvement](string) Optimize scanning for string (#12909)
---
 be/src/olap/comparison_predicate.h                 |  5 ++-
 be/src/olap/rowset/segment_v2/binary_plain_page.h  | 27 +++++++++---
 be/src/olap/rowset/segment_v2/segment_iterator.cpp | 13 ++++--
 be/src/vec/columns/column_string.cpp               | 49 ++++++++++++++++++++++
 be/src/vec/columns/column_string.h                 | 21 +---------
 be/src/vec/columns/predicate_column.h              |  7 ++--
 6 files changed, 88 insertions(+), 34 deletions(-)

diff --git a/be/src/olap/comparison_predicate.h 
b/be/src/olap/comparison_predicate.h
index 6fcb45bd3c..00c69efe89 100644
--- a/be/src/olap/comparison_predicate.h
+++ b/be/src/olap/comparison_predicate.h
@@ -518,8 +518,9 @@ private:
     uint16_t _base_loop(uint16_t* sel, uint16_t size, const uint8_t* 
__restrict null_map,
                         const TArray* __restrict data_array, const TValue& 
value) const {
         uint16_t new_size = 0;
-        for (uint16_t i = 0; i < size; ++i) {
-            uint16_t idx = sel[i];
+        uint16_t* end = sel + size;
+        for (uint16_t* cursor = sel; cursor < end; ++cursor) {
+            uint16_t idx = *cursor;
             if constexpr (is_nullable) {
                 if (_opposite ^ (!null_map[idx] && _operator(data_array[idx], 
value))) {
                     sel[new_size++] = idx;
diff --git a/be/src/olap/rowset/segment_v2/binary_plain_page.h 
b/be/src/olap/rowset/segment_v2/binary_plain_page.h
index 1242fd9b75..659df55fee 100644
--- a/be/src/olap/rowset/segment_v2/binary_plain_page.h
+++ b/be/src/olap/rowset/segment_v2/binary_plain_page.h
@@ -248,12 +248,14 @@ public:
             return Status::OK();
         }
         const size_t max_fetch = std::min(*n, static_cast<size_t>(_num_elems - 
_cur_idx));
-
         uint32_t len_array[max_fetch];
         uint32_t start_offset_array[max_fetch];
-        for (int i = 0; i < max_fetch; i++, _cur_idx++) {
-            const uint32_t start_offset = offset(_cur_idx);
-            uint32_t len = offset(_cur_idx + 1) - start_offset;
+
+        uint32_t last_offset = guarded_offset(_cur_idx);
+        for (int i = 0; i < max_fetch - 1; i++, _cur_idx++) {
+            const uint32_t start_offset = last_offset;
+            last_offset = guarded_offset(_cur_idx + 1);
+            uint32_t len = last_offset - start_offset;
             len_array[i] = len;
             start_offset_array[i] = start_offset;
             if constexpr (Type == OLAP_FIELD_TYPE_OBJECT) {
@@ -262,6 +264,14 @@ public:
                 }
             }
         }
+        _cur_idx++;
+        len_array[max_fetch - 1] = offset(_cur_idx) - last_offset;
+        start_offset_array[max_fetch - 1] = last_offset;
+        if constexpr (Type == OLAP_FIELD_TYPE_OBJECT) {
+            if (_options.need_check_bitmap) {
+                RETURN_IF_ERROR(BitmapTypeCode::validate(*(_data.data + 
last_offset)));
+            }
+        }
         dst->insert_many_binary_data(_data.mutable_data(), len_array, 
start_offset_array,
                                      max_fetch);
 
@@ -340,13 +350,20 @@ public:
     }
 
 private:
+    static constexpr size_t SIZE_OF_INT32 = sizeof(uint32_t);
     // Return the offset within '_data' where the string value with index 
'idx' can be found.
     uint32_t offset(size_t idx) const {
         if (idx >= _num_elems) {
             return _offsets_pos;
         }
         const uint8_t* p =
-                reinterpret_cast<const uint8_t*>(&_data[_offsets_pos + idx * 
sizeof(uint32_t)]);
+                reinterpret_cast<const uint8_t*>(&_data[_offsets_pos + idx * 
SIZE_OF_INT32]);
+        return decode_fixed32_le(p);
+    }
+
+    uint32_t guarded_offset(size_t idx) const {
+        const uint8_t* p =
+                reinterpret_cast<const uint8_t*>(&_data[_offsets_pos + idx * 
SIZE_OF_INT32]);
         return decode_fixed32_le(p);
     }
 
diff --git a/be/src/olap/rowset/segment_v2/segment_iterator.cpp 
b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
index 98f2cfae27..e6435e8be1 100644
--- a/be/src/olap/rowset/segment_v2/segment_iterator.cpp
+++ b/be/src/olap/rowset/segment_v2/segment_iterator.cpp
@@ -1150,8 +1150,11 @@ Status SegmentIterator::next_batch(vectorized::Block* 
block) {
         }
 
         if (!_lazy_materialization_read) {
-            Status ret = _output_column_by_sel_idx(block, 
_first_read_column_ids, sel_rowid_idx,
-                                                   selected_size);
+            Status ret = Status::OK();
+            if (selected_size > 0) {
+                ret = _output_column_by_sel_idx(block, _first_read_column_ids, 
sel_rowid_idx,
+                                                selected_size);
+            }
             if (!ret.ok()) {
                 return ret;
             }
@@ -1176,8 +1179,10 @@ Status SegmentIterator::next_batch(vectorized::Block* 
block) {
         // when lazy materialization enables, _first_read_column_ids = 
distinct(_short_cir_pred_column_ids + _vec_pred_column_ids)
         // see _vec_init_lazy_materialization
         // todo(wb) need to tell input columnids from output columnids
-        RETURN_IF_ERROR(_output_column_by_sel_idx(block, 
_first_read_column_ids, sel_rowid_idx,
-                                                  selected_size));
+        if (selected_size > 0) {
+            RETURN_IF_ERROR(_output_column_by_sel_idx(block, 
_first_read_column_ids, sel_rowid_idx,
+                                                      selected_size));
+        }
     }
 
     // shrink char_type suffix zero data
diff --git a/be/src/vec/columns/column_string.cpp 
b/be/src/vec/columns/column_string.cpp
index d988791ca0..ddc21c31d8 100644
--- a/be/src/vec/columns/column_string.cpp
+++ b/be/src/vec/columns/column_string.cpp
@@ -440,6 +440,55 @@ void ColumnString::reserve(size_t n) {
     chars.reserve(n);
 }
 
+void ColumnString::insert_many_strings(const StringRef* strings, size_t num) {
+    DCHECK_NE(num, 0);
+    offsets.reserve(offsets.size() + num);
+    std::vector<const char*> start_points(1);
+    auto& head = strings[0];
+    start_points[0] = head.data;
+    size_t new_size = head.size;
+    const char* cursor = head.data + new_size;
+    std::vector<const char*> end_points;
+
+    const size_t old_size = chars.size();
+    size_t offset = old_size;
+    offset += new_size;
+    offsets.push_back(offset);
+    if (num == 1) {
+        end_points.push_back(cursor);
+    } else {
+        for (size_t i = 1; i < num; i++) {
+            auto& str = strings[i];
+            if (cursor != str.data) {
+                end_points.push_back(cursor);
+                start_points.push_back(str.data);
+                cursor = str.data;
+            }
+            size_t sz = str.size;
+            offset += sz;
+            new_size += sz;
+            cursor += sz;
+            offsets.push_back_without_reserve(offset);
+        }
+        end_points.push_back(cursor);
+    }
+    DCHECK_EQ(end_points.size(), start_points.size());
+
+    chars.resize(old_size + new_size);
+
+    size_t num_range = start_points.size();
+    Char* data = chars.data();
+
+    offset = old_size;
+    for (size_t i = 0; i < num_range; i++) {
+        uint32_t len = end_points[i] - start_points[i];
+        if (len) {
+            memcpy(data + offset, start_points[i], len);
+            offset += len;
+        }
+    }
+}
+
 void ColumnString::resize(size_t n) {
     auto origin_size = size();
     if (origin_size > n) {
diff --git a/be/src/vec/columns/column_string.h 
b/be/src/vec/columns/column_string.h
index 469bbdc6df..a62a16be42 100644
--- a/be/src/vec/columns/column_string.h
+++ b/be/src/vec/columns/column_string.h
@@ -186,26 +186,7 @@ public:
         }
     };
 
-    void insert_many_strings(const StringRef* strings, size_t num) override {
-        size_t new_size = 0;
-        for (size_t i = 0; i < num; i++) {
-            new_size += strings[i].size;
-        }
-
-        const size_t old_size = chars.size();
-        chars.resize(old_size + new_size);
-
-        Char* data = chars.data();
-        size_t offset = old_size;
-        for (size_t i = 0; i < num; i++) {
-            uint32_t len = strings[i].size;
-            if (len) {
-                memcpy(data + offset, strings[i].data, len);
-                offset += len;
-            }
-            offsets.push_back(offset);
-        }
-    }
+    void insert_many_strings(const StringRef* strings, size_t num) override;
 
     void insert_many_dict_data(const int32_t* data_array, size_t start_index, 
const StringRef* dict,
                                size_t num, uint32_t /*dict_num*/) override {
diff --git a/be/src/vec/columns/predicate_column.h 
b/be/src/vec/columns/predicate_column.h
index d5ad52b6ac..4d44217b9a 100644
--- a/be/src/vec/columns/predicate_column.h
+++ b/be/src/vec/columns/predicate_column.h
@@ -279,9 +279,10 @@ public:
             data.resize(org_elem_num + num);
             uint32_t fragment_start_offset = start_offset_array[0];
             size_t fragment_len = 0;
-            for (size_t i = 0; i < num; i++) {
-                data[org_elem_num + i].ptr = destination + fragment_len;
-                data[org_elem_num + i].len = len_array[i];
+            StringValue* cursor = data.data() + org_elem_num;
+            for (size_t i = 0; i < num; i++, cursor++) {
+                cursor->ptr = destination + fragment_len;
+                cursor->len = len_array[i];
                 fragment_len += len_array[i];
                 // Compute the largest continuous memcpy block and copy them.
                 // If this is the last element in data array, then should copy 
the current memory block.


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

Reply via email to