From dc2e117cce48323e8c7da31278c5c68f75f63f6f Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Tue, 14 Jun 2022 17:30:11 +0200 Subject: [PATCH] UnaryLogicalFunctions improve performance using dynamic dispatch --- src/Functions/FunctionsLogical.cpp | 69 ++++++++----------- tests/performance/unary_logical_functions.xml | 31 +++++++++ 2 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 tests/performance/unary_logical_functions.xml diff --git a/src/Functions/FunctionsLogical.cpp b/src/Functions/FunctionsLogical.cpp index b615f52652c..be295186943 100644 --- a/src/Functions/FunctionsLogical.cpp +++ b/src/Functions/FunctionsLogical.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -50,17 +51,15 @@ MutableColumnPtr buildColumnFromTernaryData(const UInt8Container & ternary_data, const size_t rows_count = ternary_data.size(); auto new_column = ColumnUInt8::create(rows_count); - std::transform( - ternary_data.cbegin(), ternary_data.cend(), new_column->getData().begin(), - [](const auto x) { return x == Ternary::True; }); + for (size_t i = 0; i < rows_count; ++i) + new_column->getData()[i] = (ternary_data[i] == Ternary::True); if (!make_nullable) return new_column; auto null_column = ColumnUInt8::create(rows_count); - std::transform( - ternary_data.cbegin(), ternary_data.cend(), null_column->getData().begin(), - [](const auto x) { return x == Ternary::Null; }); + for (size_t i = 0; i < rows_count; ++i) + null_column->getData()[i] = (ternary_data[i] == Ternary::Null); return ColumnNullable::create(std::move(new_column), std::move(null_column)); } @@ -68,13 +67,14 @@ MutableColumnPtr buildColumnFromTernaryData(const UInt8Container & ternary_data, template bool tryConvertColumnToBool(const IColumn * column, UInt8Container & res) { - const auto col = checkAndGetColumn>(column); - if (!col) + const auto column_typed = checkAndGetColumn>(column); + if (!column_typed) return false; - std::transform( - col->getData().cbegin(), col->getData().cend(), res.begin(), - [](const auto x) { return !!x; }); + auto & data = column_typed->getData(); + size_t data_size = data.size(); + for (size_t i = 0; i < data_size; ++i) + res[i] = static_cast(data[i]); return true; } @@ -99,7 +99,7 @@ bool extractConstColumns(ColumnRawPtrs & in, UInt8 & res, Func && func) { bool has_res = false; - for (int i = static_cast(in.size()) - 1; i >= 0; --i) + for (Int64 i = static_cast(in.size()) - 1; i >= 0; --i) { UInt8 x; @@ -458,7 +458,9 @@ ColumnPtr basicExecuteImpl(ColumnRawPtrs arguments, size_t input_rows_count) for (const IColumn * column : arguments) { if (const auto * uint8_column = checkAndGetColumn(column)) + { uint8_args.push_back(uint8_column); + } else { auto converted_column = ColumnUInt8::create(input_rows_count); @@ -596,14 +598,14 @@ ColumnPtr FunctionAnyArityLogical::executeShortCircuit(ColumnsWithTy if (nulls) applyTernaryLogic(mask, *nulls); - MutableColumnPtr res = ColumnUInt8::create(); - typeid_cast(res.get())->getData() = std::move(mask); + auto res = ColumnUInt8::create(); + res->getData() = std::move(mask); if (!nulls) return res; - MutableColumnPtr bytemap = ColumnUInt8::create(); - typeid_cast(bytemap.get())->getData() = std::move(*nulls); + auto bytemap = ColumnUInt8::create(); + bytemap->getData() = std::move(*nulls); return ColumnNullable::create(std::move(res), std::move(bytemap)); } @@ -692,29 +694,14 @@ ColumnPtr FunctionAnyArityLogical::getConstantResultForNonConstArgum return result_column; } -template -struct UnaryOperationImpl -{ - using ResultType = typename Op::ResultType; - using ArrayA = typename ColumnVector::Container; - using ArrayC = typename ColumnVector::Container; - - static void NO_INLINE vector(const ArrayA & a, ArrayC & c) - { - std::transform( - a.cbegin(), a.cend(), c.begin(), - [](const auto x) { return Op::apply(x); }); - } -}; - template