Merge pull request #9293 from ClickHouse/akz/column_vector_replicate_faster

Made ColumnVector::replicate() implementation 3x faster
This commit is contained in:
alexey-milovidov 2020-02-22 02:23:49 +03:00 committed by GitHub
commit 5cc112e3d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 9 deletions

View File

@ -346,18 +346,14 @@ ColumnPtr ColumnVector<T>::replicate(const IColumn::Offsets & offsets) const
if (0 == size)
return this->create();
auto res = this->create();
typename Self::Container & res_data = res->getData();
res_data.reserve(offsets.back());
auto res = this->create(offsets.back());
IColumn::Offset prev_offset = 0;
auto it = res->getData().begin();
for (size_t i = 0; i < size; ++i)
{
size_t size_to_replicate = offsets[i] - prev_offset;
prev_offset = offsets[i];
for (size_t j = 0; j < size_to_replicate; ++j)
res_data.push_back(data[i]);
const auto span_end = res->getData().begin() + offsets[i];
for (; it < span_end; ++it)
*it = data[i];
}
return res;

View File

@ -186,3 +186,28 @@ TEST(column_unique, column_unique_unique_deserialize_from_arena_Nullable_String_
auto column = ColumnNullable::create(std::move(column_string), std::move(null_mask));
column_unique_unique_deserialize_from_arena_impl(*column, *data_type);
}
TEST(ColumnVector, correctness_of_replicate)
{
const auto column = ColumnUInt8::create();
column->insertValue(3);
column->insertValue(2);
column->insertValue(1);
const auto empty_column = column->replicate({0, 0, 0});
const auto empty_column_ptr = typeid_cast<const ColumnUInt8 *>(empty_column.get());
EXPECT_NE(empty_column_ptr, nullptr);
EXPECT_EQ(empty_column_ptr->size(), 0);
const auto new_column = column->replicate({1, 1, 5});
const auto new_column_ptr = typeid_cast<const ColumnUInt8 *>(new_column.get());
EXPECT_NE(new_column_ptr, nullptr);
EXPECT_EQ(new_column_ptr->size(), 5);
auto it = new_column_ptr->getData().cbegin();
for (const auto num : {3, 1, 1, 1, 1})
{
EXPECT_EQ(*it, num);
++it;
}
}