Skip to content
This repository was archived by the owner on May 10, 2024. It is now read-only.

Commit ff14d97

Browse files
xhochywesm
authored andcommitted
PARQUET-512: Add Google benchmark for performance testing
Based on @emkornfield 's work in apache/arrow#29 Author: Uwe L. Korn <uwelk@xhochy.com> Closes #93 from xhochy/parquet-512 and squashes the following commits: ebc10d2 [Uwe L. Korn] Fix signed/unsigned comparison 684dbc6 [Uwe L. Korn] Fix c&p bug 5a8e239 [Uwe L. Korn] Build benchmarks but don't run them in Travis e7dc34c [Uwe L. Korn] Remove Arrow references f6b02da [Uwe L. Korn] PARQUET-512: Add Google benchmark for performance testing
1 parent 674dbb3 commit ff14d97

16 files changed

Lines changed: 573 additions & 41 deletions

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ matrix:
2828
os: linux
2929
before_script:
3030
- source $TRAVIS_BUILD_DIR/ci/before_script_travis.sh
31-
- cmake -DCMAKE_CXX_FLAGS="-Werror" -DPARQUET_TEST_MEMCHECK=ON -DPARQUET_GENERATE_COVERAGE=1 $TRAVIS_BUILD_DIR
31+
- cmake -DCMAKE_CXX_FLAGS="-Werror" -DPARQUET_TEST_MEMCHECK=ON -DPARQUET_BUILD_BENCHMARKS=ON -DPARQUET_GENERATE_COVERAGE=1 $TRAVIS_BUILD_DIR
3232
- export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
3333
- compiler: clang
3434
os: linux

CMakeLists.txt

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
7474
option(PARQUET_USE_SSE
7575
"Build with SSE4 optimizations"
7676
OFF)
77+
option(PARQUET_BUILD_BENCHMARKS
78+
"Build the libparquet benchmark suite"
79+
OFF)
7780
option(PARQUET_BUILD_TESTS
7881
"Build the libparquet test suite"
7982
ON)
@@ -102,6 +105,60 @@ else()
102105
set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUBDIR_NAME}")
103106
endif()
104107

108+
############################################################
109+
# Benchmarking
110+
############################################################
111+
# Add a new micro benchmark, with or without an executable that should be built.
112+
# If benchmarks are enabled then they will be run along side unit tests with ctest.
113+
# 'make runbenchmark' and 'make unittest' to build/run only benchmark or unittests,
114+
# respectively.
115+
#
116+
# REL_BENCHMARK_NAME is the name of the benchmark app. It may be a single component
117+
# (e.g. monotime-benchmark) or contain additional components (e.g.
118+
# net/net_util-benchmark). Either way, the last component must be a globally
119+
# unique name.
120+
121+
# The benchmark will registered as unit test with ctest with a label
122+
# of 'benchmark'.
123+
#
124+
# Arguments after the test name will be passed to set_tests_properties().
125+
function(ADD_PARQUET_BENCHMARK REL_BENCHMARK_NAME)
126+
if(NOT PARQUET_BUILD_BENCHMARKS)
127+
return()
128+
endif()
129+
get_filename_component(BENCHMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE)
130+
131+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME}.cc)
132+
# This benchmark has a corresponding .cc file, set it up as an executable.
133+
set(BENCHMARK_PATH "${EXECUTABLE_OUTPUT_PATH}/${BENCHMARK_NAME}")
134+
add_executable(${BENCHMARK_NAME} "${REL_BENCHMARK_NAME}.cc")
135+
target_link_libraries(${BENCHMARK_NAME} ${PARQUET_BENCHMARK_LINK_LIBS})
136+
add_dependencies(runbenchmark ${BENCHMARK_NAME})
137+
set(NO_COLOR "--color_print=false")
138+
else()
139+
# No executable, just invoke the benchmark (probably a script) directly.
140+
set(BENCHMARK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME})
141+
set(NO_COLOR "")
142+
endif()
143+
144+
add_test(${BENCHMARK_NAME}
145+
${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} benchmark ${BENCHMARK_PATH} ${NO_COLOR})
146+
set_tests_properties(${BENCHMARK_NAME} PROPERTIES LABELS "benchmark")
147+
if(ARGN)
148+
set_tests_properties(${BENCHMARK_NAME} PROPERTIES ${ARGN})
149+
endif()
150+
endfunction()
151+
152+
# A wrapper for add_dependencies() that is compatible with NO_BENCHMARKS.
153+
function(ADD_PARQUET_BENCHMARK_DEPENDENCIES REL_BENCHMARK_NAME)
154+
if(NOT PARQUET_BUILD_BENCHMARKS)
155+
return()
156+
endif()
157+
get_filename_component(BENCMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE)
158+
159+
add_dependencies(${BENCHMARK_NAME} ${ARGN})
160+
endfunction()
161+
105162
############################################################
106163
# Testing
107164
############################################################
@@ -113,6 +170,9 @@ endif()
113170
# net/net_util-test). Either way, the last component must be a globally
114171
# unique name.
115172
#
173+
# The unit test is added with a label of "unittest" to support filtering with
174+
# ctest.
175+
#
116176
# Arguments after the test name will be passed to set_tests_properties().
117177
function(ADD_PARQUET_TEST REL_TEST_NAME)
118178
if(NOT PARQUET_BUILD_TESTS)
@@ -124,6 +184,7 @@ function(ADD_PARQUET_TEST REL_TEST_NAME)
124184
# This test has a corresponding .cc file, set it up as an executable.
125185
set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}")
126186
add_executable(${TEST_NAME} "${REL_TEST_NAME}.cc")
187+
add_dependencies(unittest ${TEST_NAME})
127188

128189
if(APPLE)
129190
# On OS X / Thrift >= 0.9.2, tr1/tuple.h is not in libc++
@@ -149,8 +210,9 @@ function(ADD_PARQUET_TEST REL_TEST_NAME)
149210
valgrind --tool=memcheck --leak-check=full --error-exitcode=1 ${TEST_PATH})
150211
else()
151212
add_test(${TEST_NAME}
152-
${BUILD_SUPPORT_DIR}/run-test.sh ${TEST_PATH})
213+
${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} test ${TEST_PATH})
153214
endif()
215+
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "unittest")
154216
if(ARGN)
155217
set_tests_properties(${TEST_NAME} PROPERTIES ${ARGN})
156218
endif()
@@ -213,11 +275,26 @@ add_library(zlibstatic STATIC IMPORTED)
213275
set_target_properties(zlibstatic PROPERTIES IMPORTED_LOCATION ${ZLIB_STATIC_LIB})
214276

215277
## GTest
278+
add_custom_target(unittest ctest -L unittest)
216279
find_package(GTest REQUIRED)
217280
include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
218281
add_library(gtest STATIC IMPORTED)
219282
set_target_properties(gtest PROPERTIES IMPORTED_LOCATION ${GTEST_STATIC_LIB})
220283

284+
## Google Benchmark
285+
if ("$ENV{GBENCHMARK_HOME}" STREQUAL "")
286+
set(GBENCHMARK_HOME ${THIRDPARTY_DIR}/installed)
287+
endif()
288+
289+
if(PARQUET_BUILD_BENCHMARKS)
290+
add_custom_target(runbenchmark ctest -L benchmark)
291+
find_package(GBenchmark REQUIRED)
292+
include_directories(SYSTEM ${GBENCHMARK_INCLUDE_DIR})
293+
message(${GBENCHMARK_STATIC_LIB})
294+
add_library(gbenchmark STATIC IMPORTED)
295+
set_target_properties(gbenchmark PROPERTIES IMPORTED_LOCATION ${GBENCHMARK_STATIC_LIB})
296+
endif()
297+
221298
# Thrift requires these definitions for some types that we use
222299
add_definitions(-DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -DHAVE_NETDB_H)
223300
add_definitions(-fPIC)
@@ -331,6 +408,11 @@ set(PARQUET_MIN_TEST_LIBS
331408
parquet)
332409
set(PARQUET_TEST_LINK_LIBS ${PARQUET_MIN_TEST_LIBS})
333410

411+
#############################################################
412+
# Benchmark linking
413+
414+
set(PARQUET_BENCHMARK_LINK_LIBS parquet parquet_benchmark_main)
415+
334416
#############################################################
335417
# Code coverage
336418

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- zlib
2525
- thrift 0.7+ [install instructions](https://thrift.apache.org/docs/install/)
2626
- googletest 1.7.0 (cannot be installed with package managers)
27+
- Google Benchmark (only required if building benchmarks)
2728

2829
You can install these dependencies using a package manager or using the
2930
`thirdparty/` scripts in this repository. On Homebrew, you can run:
@@ -87,7 +88,7 @@ This library uses Google's `googletest` unit test framework. After building
8788
with `make`, you can run the test suite by running
8889

8990
```
90-
ctest
91+
make unittest
9192
```
9293

9394
The test suite relies on an environment variable `PARQUET_TEST_DATA` pointing
@@ -107,6 +108,19 @@ you can use valgrind with ctest to look for memory leaks:
107108
valgrind --tool=memcheck --leak-check=yes ctest
108109
```
109110

111+
## Building/Running benchmarks
112+
113+
Follow the directions for simple build except run cmake
114+
with the `--PARQUET_BUILD_BENCHMARKS` parameter set correctly:
115+
116+
cmake -DPARQUET_BUILD_BENCHMARKS=ON ..
117+
118+
and instead of make unittest run either `make; ctest` to run both unit tests
119+
and benchmarks or `make runbenchmark` to run only the benchmark tests.
120+
121+
Benchmark logs will be placed in the build directory under `build/benchmark-logs`.
122+
123+
110124
## Out-of-source builds
111125

112126
parquet-cpp supports out of source builds. For example:
@@ -116,7 +130,7 @@ mkdir test-build
116130
cd test-build
117131
cmake ..
118132
make
119-
ctest
133+
ctest -L unittest
120134
```
121135

122136
By using out-of-source builds you can preserve your current build state in case
@@ -172,7 +186,7 @@ mkdir coverage-build
172186
cd coverage-build
173187
cmake -DPARQUET_GENERATE_COVERAGE=1
174188
make -j$PARALLEL
175-
ctest
189+
ctest -L unittest
176190
```
177191

178192
The `gcov` artifacts are not located in a place that works well with either
@@ -205,4 +219,4 @@ coveralls -t $PARQUET_CPP_COVERAGE_TOKEN --gcov-options '\-l' -r $PARQUET_ROOT -
205219

206220

207221
Note that `gcov` throws off artifacts from the STL, so I excluded my toolchain
208-
root stored in `$NATIVE_TOOLCHAIN` to avoid a cluttered coverage report.
222+
root stored in `$NATIVE_TOOLCHAIN` to avoid a cluttered coverage report.

0 commit comments

Comments
 (0)