Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
atod-benchmark.cc
Go to the documentation of this file.
1 // Copyright 2015 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <iostream>
18 #include <vector>
19 #include <sstream>
20 #include "runtime/string-value.h"
21 #include "util/benchmark.h"
22 #include "util/cpu-info.h"
23 #include "util/string-parser.h"
24 
25 #include "common/names.h"
26 
27 using namespace impala;
28 
29 // Machine Info: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
30 // atod: Function Rate (iters/ms) Comparison
31 //----------------------------------------------------------------------
32 // Impala Decimal4 84.6 1X
33 // Impala Decimal8 49.77 0.5883X
34 // Impala Decimal16 17.08 0.2019X
35 
36 template <typename Decimal>
37 struct TestData {
38  int precision;
39  int scale;
41  vector<StringValue> data;
42  vector<string> memory;
43  vector<Decimal> result;
44 };
45 
46 double Rand() {
47  return rand() / static_cast<double>(RAND_MAX);
48 }
49 
50 template <typename Decimal>
51 void AddTestData(TestData<Decimal>* data, const string& input) {
52  data->memory.push_back(input);
53  const string& str = data->memory.back();
54  data->data.push_back(StringValue(const_cast<char*>(str.c_str()), str.length()));
55 }
56 
57 template <typename Decimal>
58 void AddTestData(TestData<Decimal>* data, int n) {
59  int128_t max_whole = data->precision > data->scale ?
60  DecimalUtil::GetScaleMultiplier<int128_t>(data->precision - data->scale) - 1 : 0;
61  int128_t max_fraction = data->scale > 0 ?
62  DecimalUtil::GetScaleMultiplier<int128_t>(data->scale) - 1 : 0;
63  for (int i = 0; i < n; ++i) {
64  stringstream ss;
65  if (data->probability_negative > Rand()) ss << "-";
66  if (max_whole > 0) ss << static_cast<int128_t>(max_whole * Rand());
67  if (max_fraction > 0) ss << "." << static_cast<int128_t>(max_fraction * Rand());
68  AddTestData(data, ss.str());
69  }
70 }
71 
72 template <typename Decimal, typename Storage>
73 void TestImpala(int batch_size, void* d) {
74  TestData<Decimal>* data = reinterpret_cast<TestData<Decimal>*>(d);
75  ColumnType column_type = ColumnType::CreateDecimalType(data->precision, data->scale);
76  Decimal val;
77  for (int i = 0; i < batch_size; ++i) {
78  int n = data->data.size();
79  for (int j = 0; j < n; ++j) {
80  const StringValue& str = data->data[j];
82  val = StringParser::StringToDecimal<Storage>(
83  str.ptr, str.len, column_type, &dummy);
84  data->result[j] = val;
85  }
86  }
87 }
88 
89 int main(int argc, char **argv) {
90  CpuInfo::Init();
91  cout << Benchmark::GetMachineInfo() << endl;
92 
93  Benchmark suite("atod");
94 
97  data4.scale = data4.precision / 2;
98  data4.probability_negative = 0.25;
99  AddTestData(&data4, 1000);
100  data4.result.resize(data4.data.size());
101  suite.AddBenchmark("Impala Decimal4", TestImpala<Decimal4Value, int32_t>, &data4);
102 
105  data8.scale = data8.precision / 2;
106  data8.probability_negative = 0.25;
107  AddTestData(&data8, 1000);
108  data8.result.resize(data8.data.size());
109  suite.AddBenchmark("Impala Decimal8", TestImpala<Decimal8Value, int64_t>, &data8);
110 
113  data16.scale = data16.precision / 2;
114  data16.probability_negative = 0.25;
115  AddTestData(&data16, 1000);
116  data16.result.resize(data16.data.size());
117  suite.AddBenchmark("Impala Decimal16", TestImpala<Decimal16Value, int128_t>, &data16);
118 
119  cout << suite.Measure();
120  return 0;
121 }
vector< string > memory
double probability_negative
int AddBenchmark(const std::string &name, BenchmarkFunction fn, void *args, int baseline_idx=0)
Definition: benchmark.cc:70
static const int MAX_DECIMAL8_PRECISION
The maximum precision representable by a 8-byte decimal (Decimal8Value)
Definition: types.h:77
void AddTestData(TestData< Decimal > *data, const string &input)
static std::string GetMachineInfo()
Output machine/build configuration as a string.
Definition: benchmark.cc:124
std::string Measure()
Runs all the benchmarks and returns the result in a formatted string.
Definition: benchmark.cc:83
void TestImpala(int batch_size, void *d)
static const int MAX_DECIMAL4_PRECISION
The maximum precision representable by a 4-byte decimal (Decimal4Value)
Definition: types.h:75
int main(int argc, char **argv)
double Rand()
vector< StringValue > data
vector< Decimal > result
static void Init()
Initialize CpuInfo.
Definition: cpu-info.cc:75
static ColumnType CreateDecimalType(int precision, int scale)
Definition: types.h:103
static const int MAX_PRECISION
Must be kept in sync with FE's max precision/scale.
Definition: types.h:71
__int128_t int128_t
We use the c++ int128_t type. This is stored using 16 bytes and very performant.