From e659615587d38ab5f386535f91de3b85bccb4c28 Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Mon, 15 Apr 2024 11:28:23 -0400 Subject: [PATCH] DistanceOp: Add short-circuit for point-point distance --- benchmarks/operation/CMakeLists.txt | 10 ++++++ benchmarks/operation/DistancePerfTest.cpp | 40 +++++++++++++++++++++++ src/operation/distance/DistanceOp.cpp | 4 +++ 3 files changed, 54 insertions(+) create mode 100644 benchmarks/operation/DistancePerfTest.cpp diff --git a/benchmarks/operation/CMakeLists.txt b/benchmarks/operation/CMakeLists.txt index 10b0eb4884..8df2a6bfd0 100644 --- a/benchmarks/operation/CMakeLists.txt +++ b/benchmarks/operation/CMakeLists.txt @@ -10,3 +10,13 @@ ################################################################################ add_subdirectory(buffer) add_subdirectory(predicate) + +if (benchmark_FOUND) + add_executable(perf_distance DistancePerfTest.cpp) + target_include_directories(perf_distance PUBLIC + $ + $ + $) + target_link_libraries(perf_distance PRIVATE + benchmark::benchmark geos geos_cxx_flags) +endif() diff --git a/benchmarks/operation/DistancePerfTest.cpp b/benchmarks/operation/DistancePerfTest.cpp new file mode 100644 index 0000000000..7bdcb71346 --- /dev/null +++ b/benchmarks/operation/DistancePerfTest.cpp @@ -0,0 +1,40 @@ +/********************************************************************** + * + * GEOS - Geometry Engine Open Source + * http://geos.osgeo.org + * + * Copyright (C) 2024 Daniel Baston + * + * This is free software; you can redistribute and/or modify it under + * the terms of the GNU Lesser General Public Licence as published + * by the Free Software Foundation. + * See the COPYING file for more information. + * + **********************************************************************/ + +#include + +#include +#include +#include +#include + +using geos::operation::distance::DistanceOp; + +static void BM_PointPointDistance(benchmark::State& state) { + geos::geom::Envelope e(-100, 100, -100, 100); + auto points = geos::benchmark::createPoints(e, 100000); + + for (auto _ : state) { + for (std::size_t i = 0; i < points.size(); i++) { + for (std::size_t j = 0; i < points.size(); i++) { + points[i]->distance(points[j].get()); + } + } + } +} + +BENCHMARK(BM_PointPointDistance); + +BENCHMARK_MAIN(); + diff --git a/src/operation/distance/DistanceOp.cpp b/src/operation/distance/DistanceOp.cpp index 952c68d96c..fc19c31f73 100644 --- a/src/operation/distance/DistanceOp.cpp +++ b/src/operation/distance/DistanceOp.cpp @@ -110,6 +110,10 @@ DistanceOp::distance() if(geom[0]->isEmpty() || geom[1]->isEmpty()) { return 0.0; } + if(geom[0]->getGeometryTypeId() == GEOS_POINT && geom[1]->getGeometryTypeId() == GEOS_POINT) { + return static_cast(geom[0])->getCoordinate()->distance(*static_cast(geom[1])->getCoordinate()); + } + computeMinDistance(); return minDistance; }