Skip to content

Commit

Permalink
chore(dev/benchmarks): Benchmark coordinate sequence iteration (#112)
Browse files Browse the repository at this point in the history
This PR benchmarks coordinate iteration (and fixes the previous
benchmarks benchmark the same cases). Some takeaways:

- In C, `GEOARROW_COORD_VIEW_VALUE()`, which uses `i * coord_stride`,
seems to prevent the compiler from doing some optimization which is
possible when incrementing the pointer by `coord_stride` in each
iteration of the loop. However, this only affects bounds calculation and
not the centroid calculation.
- In C++, the STL iterator does a slightly better job optimizing `i *
coord_stride` and in one case seems to do slightly better.

This PR also adds "dimension iterators" `dbegin()` and `dend()` for
iterating over a particular dimension.

My personal takeaway is that except for possibly very cheap operations
(like bounding, winding, and centroid calculations), C++ STL iteration
is probably fine. A good reason to use dimension-specific iteration is
if you are specifically aiming for autovectorization of some kind (or if
you specifically are discarding values from another dimension).
  • Loading branch information
paleolimbot authored Jan 7, 2025
1 parent b926c18 commit db02936
Show file tree
Hide file tree
Showing 9 changed files with 509 additions and 331 deletions.
7 changes: 3 additions & 4 deletions dev/benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if(NOT DEFINED CMAKE_C_STANDARD)
endif()

if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()

Expand Down Expand Up @@ -58,7 +58,6 @@ if(IS_DIRECTORY "${GEOARROW_BENCHMARK_SOURCE_URL}")
elseif(NOT "${GEOARROW_BENCHMARK_SOURCE_URL}" STREQUAL "")
fetchcontent_declare(geoarrow URL "${GEOARROW_BENCHMARK_SOURCE_URL}")
fetchcontent_makeavailable(geoarrow)
fetchcontent_makeavailable(geoarrow_ipc)
endif()

# Check that either the parent scope or this CMakeLists.txt defines a geoarrow target
Expand All @@ -74,8 +73,8 @@ endif()
include(CTest)
enable_testing()

foreach(ITEM array_view)
add_executable(${ITEM}_benchmark "c/${ITEM}_benchmark.cc" c/benchmark_lib.cc)
foreach(ITEM coord_view hpp_coord_sequence)
add_executable(${ITEM}_benchmark "c/${ITEM}_benchmark.cc")
target_link_libraries(${ITEM}_benchmark PRIVATE geoarrow benchmark::benchmark_main)
add_test(NAME ${ITEM}_benchmark COMMAND ${ITEM}_benchmark
--benchmark_out=${ITEM}_benchmark.json)
Expand Down
142 changes: 0 additions & 142 deletions dev/benchmarks/c/array_view_benchmark.cc

This file was deleted.

152 changes: 0 additions & 152 deletions dev/benchmarks/c/benchmark_lib.cc

This file was deleted.

26 changes: 0 additions & 26 deletions dev/benchmarks/c/benchmark_lib.h

This file was deleted.

38 changes: 38 additions & 0 deletions dev/benchmarks/c/benchmark_util.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

#include <cmath>
#include <cstdlib>

namespace geoarrow {

namespace benchmark_util {

static const int64_t kNumCoordsPrettyBig = 10000000;

static inline void PointsOnCircle(uint32_t n, uint32_t stride, double* out_x,
double* out_y, double dangle_radians = M_PI / 100.0,
double radius = 483.0) {
double angle = 0;

for (uint32_t i = 0; i < n; i++) {
*out_x = std::cos(angle) * radius;
*out_y = std::sin(angle) * radius;
angle += dangle_radians;
out_x += stride;
out_y += stride;
}
}

static inline void FillRandom(uint32_t n, uint32_t stride, double* out,
uint32_t seed = 1234, double range_min = -1.0,
double range_max = 1.0) {
std::srand(seed);
double range = range_max - range_max;
for (uint32_t i = 0; i < n; i++) {
double value01 = static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX);
*out = range_min + value01 * range;
out += stride;
}
}

} // namespace benchmark_util
} // namespace geoarrow
Loading

0 comments on commit db02936

Please sign in to comment.