blob: b6aac2445c8a01c4044b1b00938be82ba04b910d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <Columns/IColumn.h>
#include <Core/Block.h>
#include <DataTypes/DataTypeFactory.h>
#include <DataTypes/IDataType.h>
#include <Functions/FunctionFactory.h>
#include <Functions/SparkFunctionDivide.h>
#include <Interpreters/ActionsDAG.h>
#include <Interpreters/ExpressionActions.h>
#include <Processors/Executors/PipelineExecutor.h>
#include <Processors/Sources/BlocksSource.h>
#include <benchmark/benchmark.h>
#include <Common/QueryContext.h>
using namespace DB;
static Block createDataBlock(String name1, String name2, size_t rows)
{
auto type = DataTypeFactory::instance().get("Float64");
auto column1 = type->createColumn();
auto column2 = type->createColumn();
for (size_t i = 0; i < rows; ++i)
{
double d = i * 1.0;
column1->insert(d);
column2->insert(0);
}
ColumnWithTypeAndName col_type_name_1(std::move(column1), type, name1);
ColumnWithTypeAndName col_type_name_2(std::move(column2), type, name2);
Block block;
block.insert(col_type_name_1);
block.insert(col_type_name_2);
return std::move(block);
}
static std::string join(const ActionsDAG::NodeRawConstPtrs & v, char c)
{
std::string res;
for (size_t i = 0; i < v.size(); ++i)
{
if (i)
res += c;
res += v[i]->result_name;
}
return res;
}
static const ActionsDAG::Node *
addFunction(ActionsDAG & actions_dag, const String & function, const DB::ActionsDAG::NodeRawConstPtrs & args)
{
auto function_builder = FunctionFactory::instance().get(function, local_engine::QueryContext::globalContext());
std::string args_name = join(args, ',');
auto result_name = function + "(" + args_name + ")";
return &actions_dag.addFunction(function_builder, args, result_name);
}
static void BM_CHDivideFunction(benchmark::State & state)
{
ActionsDAG dag;
Block block = createDataBlock("d1", "d2", 30000000);
ColumnWithTypeAndName col1 = block.getByPosition(0);
ColumnWithTypeAndName col2 = block.getByPosition(1);
const ActionsDAG::Node * left_arg = &dag.addColumn(col1);
const ActionsDAG::Node * right_arg = &dag.addColumn(col2);
addFunction(dag, "divide", {left_arg, right_arg});
ExpressionActions expr_actions(std::move(dag));
for (auto _ : state)
expr_actions.execute(block);
}
static void BM_SparkDivideFunction(benchmark::State & state)
{
ActionsDAG dag;
Block block = createDataBlock("d1", "d2", 30000000);
ColumnWithTypeAndName col1 = block.getByPosition(0);
ColumnWithTypeAndName col2 = block.getByPosition(1);
const ActionsDAG::Node * left_arg = &dag.addColumn(col1);
const ActionsDAG::Node * right_arg = &dag.addColumn(col2);
addFunction(dag, "sparkDivide", {left_arg, right_arg});
ExpressionActions expr_actions(std::move(dag));
for (auto _ : state)
expr_actions.execute(block);
}
static void BM_GlutenDivideFunctionParser(benchmark::State & state)
{
ActionsDAG dag;
Block block = createDataBlock("d1", "d2", 30000000);
ColumnWithTypeAndName col1 = block.getByPosition(0);
ColumnWithTypeAndName col2 = block.getByPosition(1);
const ActionsDAG::Node * left_arg = &dag.addColumn(col1);
const ActionsDAG::Node * right_arg = &dag.addColumn(col2);
const ActionsDAG::Node * divide_arg = addFunction(dag, "divide", {left_arg, right_arg});
DataTypePtr float64_type = std::make_shared<DataTypeFloat64>();
ColumnWithTypeAndName col_zero(float64_type->createColumnConst(1, 0), float64_type, toString(0));
ColumnWithTypeAndName col_null(float64_type->createColumnConst(1, Field{}), float64_type, "null");
const ActionsDAG::Node * zero_arg = &dag.addColumn(col_zero);
const ActionsDAG::Node * null_arg = &dag.addColumn(col_null);
const ActionsDAG::Node * equals_arg = addFunction(dag, "equals", {right_arg, zero_arg});
const ActionsDAG::Node * if_arg = addFunction(dag, "if", {equals_arg, null_arg, divide_arg});
ExpressionActions expr_actions(std::move(dag));
for (auto _ : state)
expr_actions.execute(block);
}
BENCHMARK(BM_CHDivideFunction)->Unit(benchmark::kMillisecond)->Iterations(10);
BENCHMARK(BM_SparkDivideFunction)->Unit(benchmark::kMillisecond)->Iterations(10);
BENCHMARK(BM_GlutenDivideFunctionParser)->Unit(benchmark::kMillisecond)->Iterations(10);