Skip to content

Commit 55d3fc4

Browse files
xin-zhang2yingsu00
authored andcommitted
Add PartitionedVector benchmark
1 parent fe85841 commit 55d3fc4

2 files changed

Lines changed: 194 additions & 0 deletions

File tree

velox/vector/benchmarks/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ target_link_libraries(
4545
gflags::gflags
4646
glog::glog
4747
)
48+
49+
add_executable(velox_vector_partitioned_vector_benchmark PartitionedVectorBenchmark.cpp)
50+
target_link_libraries(
51+
velox_vector_partitioned_vector_benchmark
52+
velox_dwio_common_test_utils
53+
velox_vector
54+
velox_vector_test_lib
55+
Folly::folly
56+
Folly::follybenchmark
57+
)
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <absl/random/uniform_int_distribution.h>
18+
#include <folly/Benchmark.h>
19+
#include <folly/init/Init.h>
20+
21+
#include <algorithm>
22+
23+
#include "dwio/common/tests/utils/BatchMaker.h"
24+
#include "vector/PartitionedVector.h"
25+
26+
using namespace facebook::velox;
27+
using namespace facebook::velox::test;
28+
29+
namespace facebook::velox::test {
30+
31+
namespace {
32+
33+
thread_local auto gen = std::mt19937(42);
34+
35+
auto noNulls = [](vector_size_t) { return false; };
36+
37+
auto allNulls = [](vector_size_t) { return true; };
38+
39+
auto halfNulls = [](vector_size_t row) { return row % 2 == 0; };
40+
41+
template <TypeKind T>
42+
RowTypePtr scalarTypeGenerator(int32_t numColumns) {
43+
return ROW(std::vector<TypePtr>(numColumns, createScalarType<T>()));
44+
}
45+
46+
RowTypePtr dateTypeGenerator(int32_t numColumns) {
47+
return ROW(std::vector<TypePtr>(numColumns, DATE()));
48+
}
49+
50+
RowTypePtr shortDecimalTypeGenerator(int32_t numColumns) {
51+
return ROW(std::vector<TypePtr>(numColumns, DECIMAL(10, 2)));
52+
}
53+
54+
RowTypePtr longDecimalTypeGenerator(int32_t numColumns) {
55+
return ROW(std::vector<TypePtr>(numColumns, DECIMAL(20, 3)));
56+
}
57+
58+
RowTypePtr mixedFlatTypeGenerator(int32_t numColumns) {
59+
const std::vector<TypePtr> typeSelection = {
60+
BOOLEAN(),
61+
TINYINT(),
62+
SMALLINT(),
63+
INTEGER(),
64+
BIGINT(),
65+
HUGEINT(),
66+
REAL(),
67+
DOUBLE(),
68+
TIMESTAMP(),
69+
DATE(),
70+
DECIMAL(10, 2),
71+
DECIMAL(20, 3),
72+
};
73+
74+
std::vector<TypePtr> types;
75+
types.reserve(numColumns);
76+
77+
for (int i = 0; i < numColumns; ++i) {
78+
types.push_back(typeSelection[i % typeSelection.size()]);
79+
}
80+
81+
std::ranges::shuffle(types, gen);
82+
83+
return ROW(std::move(types));
84+
}
85+
86+
auto randomPartitionFunction = [](const RowVectorPtr& vector,
87+
uint32_t numPartitions,
88+
std::vector<uint32_t>& partitions) {
89+
partitions.resize(vector->size());
90+
for (int i = 0; i < vector->size(); ++i) {
91+
partitions[i] = gen() % numPartitions;
92+
}
93+
};
94+
95+
std::shared_ptr<memory::MemoryPool> pool;
96+
std::vector<uint32_t> partitions;
97+
98+
RowVectorPtr createTestVector(
99+
const std::function<RowTypePtr(int32_t)>& rowTypeGenerator,
100+
vector_size_t numRows,
101+
int32_t numColumns,
102+
const std::function<bool(vector_size_t)>& isNullAt) {
103+
auto rowType = rowTypeGenerator(numColumns);
104+
const auto batch = BatchMaker::createBatch(rowType, numRows, *pool, isNullAt);
105+
return std::static_pointer_cast<RowVector>(batch);
106+
}
107+
108+
} // namespace
109+
110+
void runBM(
111+
uint32_t iterations,
112+
const std::function<RowTypePtr(int32_t)>& rowTypeGenerator,
113+
int32_t numColumns,
114+
uint32_t numPartitions,
115+
const std::function<bool(vector_size_t)>& isNullAt = noNulls,
116+
vector_size_t numRows = 10000) {
117+
folly::BenchmarkSuspender suspender;
118+
PartitionBuildContext ctx;
119+
auto vector =
120+
createTestVector(rowTypeGenerator, numRows, numColumns, isNullAt);
121+
randomPartitionFunction(vector, numPartitions, partitions);
122+
for (uint32_t i = 0; i < iterations; ++i) {
123+
// PartitionedVector::create mutates its input, so each iteration needs a
124+
// fresh copy to keep inputs consistent.
125+
const auto vectorCopy = std::static_pointer_cast<RowVector>(
126+
BaseVector::copy(*vector, pool.get()));
127+
suspender.dismiss();
128+
PartitionedVector::create(
129+
vectorCopy, partitions, numPartitions, ctx, pool.get());
130+
suspender.rehire();
131+
}
132+
}
133+
134+
#define BENCHMARK_CONFIG(name, generator, numCols, nulls, numParts) \
135+
BENCHMARK_NAMED_PARAM( \
136+
runBM, \
137+
name##_##numCols##Cols_##nulls##_P##numParts, \
138+
generator, \
139+
numCols, \
140+
numParts, \
141+
nulls);
142+
143+
#define BENCHMARK_PARTITIONS(name, generator, numCols, nulls) \
144+
BENCHMARK_CONFIG(name, generator, numCols, nulls, 4) \
145+
BENCHMARK_CONFIG(name, generator, numCols, nulls, 16) \
146+
BENCHMARK_CONFIG(name, generator, numCols, nulls, 64) \
147+
BENCHMARK_CONFIG(name, generator, numCols, nulls, 256) \
148+
BENCHMARK_CONFIG(name, generator, numCols, nulls, 1024)
149+
150+
#define BENCHMARK_SIZES(name, generator, nulls) \
151+
BENCHMARK_PARTITIONS(name, generator, 1, nulls) \
152+
BENCHMARK_PARTITIONS(name, generator, 10, nulls) \
153+
BENCHMARK_PARTITIONS(name, generator, 100, nulls) \
154+
BENCHMARK_PARTITIONS(name, generator, 1000, nulls)
155+
156+
#define BENCHMARK_TYPE(name, generator) \
157+
BENCHMARK_SIZES(name, generator, noNulls) \
158+
BENCHMARK_SIZES(name, generator, allNulls) \
159+
BENCHMARK_SIZES(name, generator, halfNulls)
160+
161+
BENCHMARK_TYPE(BOOLEAN, scalarTypeGenerator<TypeKind::BOOLEAN>);
162+
BENCHMARK_TYPE(SMALLINT, scalarTypeGenerator<TypeKind::SMALLINT>);
163+
BENCHMARK_TYPE(INTEGER, scalarTypeGenerator<TypeKind::INTEGER>);
164+
BENCHMARK_TYPE(BIGINT, scalarTypeGenerator<TypeKind::BIGINT>);
165+
BENCHMARK_TYPE(HUGEINT, scalarTypeGenerator<TypeKind::HUGEINT>);
166+
BENCHMARK_TYPE(REAL, scalarTypeGenerator<TypeKind::REAL>);
167+
BENCHMARK_TYPE(DOUBLE, scalarTypeGenerator<TypeKind::DOUBLE>);
168+
BENCHMARK_TYPE(TIMESTAMP, scalarTypeGenerator<TypeKind::TIMESTAMP>);
169+
BENCHMARK_TYPE(VARCHAR, scalarTypeGenerator<TypeKind::VARCHAR>);
170+
BENCHMARK_TYPE(VARBINARY, scalarTypeGenerator<TypeKind::VARBINARY>);
171+
BENCHMARK_TYPE(DATE, dateTypeGenerator);
172+
BENCHMARK_TYPE(ShortDecimal, shortDecimalTypeGenerator);
173+
BENCHMARK_TYPE(LongDecimal, longDecimalTypeGenerator);
174+
BENCHMARK_TYPE(Mixed, mixedFlatTypeGenerator);
175+
176+
} // namespace facebook::velox::test
177+
178+
int main(int argc, char** argv) {
179+
folly::Init init{&argc, &argv};
180+
memory::MemoryManager::initialize(memory::MemoryManager::Options{});
181+
pool = memory::memoryManager()->addLeafPool();
182+
folly::runBenchmarks();
183+
return 0;
184+
}

0 commit comments

Comments
 (0)