blob: 1e86844b30b21665ccbc56de14243ac1144de7ae [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 <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <sstream>
#include "runtime/string-value.h"
#include "util/benchmark.h"
#include "util/cpu-info.h"
#include "util/string-parser.h"
#include "common/names.h"
using namespace impala;
// Machine Info: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
// atod: Function Rate (iters/ms) Comparison
//----------------------------------------------------------------------
// Impala Decimal4 84.6 1X
// Impala Decimal8 49.77 0.5883X
// Impala Decimal16 17.08 0.2019X
template <typename Decimal>
struct TestData {
int precision;
int scale;
double probability_negative;
vector<StringValue> data;
vector<string> memory;
vector<Decimal> result;
};
double Rand() {
return rand() / static_cast<double>(RAND_MAX);
}
template <typename Decimal>
void AddTestData(TestData<Decimal>* data, const string& input) {
data->memory.push_back(input);
const string& str = data->memory.back();
data->data.push_back(StringValue(const_cast<char*>(str.c_str()), str.length()));
}
template <typename Decimal>
void AddTestData(TestData<Decimal>* data, int n) {
int128_t max_whole = data->precision > data->scale ?
DecimalUtil::GetScaleMultiplier<int128_t>(data->precision - data->scale) - 1 : 0;
int128_t max_fraction = data->scale > 0 ?
DecimalUtil::GetScaleMultiplier<int128_t>(data->scale) - 1 : 0;
for (int i = 0; i < n; ++i) {
stringstream ss;
if (data->probability_negative > Rand()) ss << "-";
if (max_whole > 0) ss << static_cast<int128_t>(max_whole * Rand());
if (max_fraction > 0) ss << "." << static_cast<int128_t>(max_fraction * Rand());
AddTestData(data, ss.str());
}
}
template <typename Decimal, typename Storage>
void TestImpala(int batch_size, void* d) {
TestData<Decimal>* data = reinterpret_cast<TestData<Decimal>*>(d);
ColumnType column_type = ColumnType::CreateDecimalType(data->precision, data->scale);
Decimal val;
for (int i = 0; i < batch_size; ++i) {
int n = data->data.size();
for (int j = 0; j < n; ++j) {
const StringValue& str = data->data[j];
StringParser::ParseResult dummy;
val = StringParser::StringToDecimal<Storage>(
str.ptr, str.len, column_type, false, &dummy);
data->result[j] = val;
}
}
}
int main(int argc, char **argv) {
CpuInfo::Init();
cout << Benchmark::GetMachineInfo() << endl;
Benchmark suite("atod");
TestData<Decimal4Value> data4;
data4.precision = ColumnType::MAX_DECIMAL4_PRECISION;
data4.scale = data4.precision / 2;
data4.probability_negative = 0.25;
AddTestData(&data4, 1000);
data4.result.resize(data4.data.size());
suite.AddBenchmark("Impala Decimal4", TestImpala<Decimal4Value, int32_t>, &data4);
TestData<Decimal8Value> data8;
data8.precision = ColumnType::MAX_DECIMAL8_PRECISION;
data8.scale = data8.precision / 2;
data8.probability_negative = 0.25;
AddTestData(&data8, 1000);
data8.result.resize(data8.data.size());
suite.AddBenchmark("Impala Decimal8", TestImpala<Decimal8Value, int64_t>, &data8);
TestData<Decimal16Value> data16;
data16.precision = ColumnType::MAX_PRECISION;
data16.scale = data16.precision / 2;
data16.probability_negative = 0.25;
AddTestData(&data16, 1000);
data16.result.resize(data16.data.size());
suite.AddBenchmark("Impala Decimal16", TestImpala<Decimal16Value, int128_t>, &data16);
cout << suite.Measure();
return 0;
}