Added benchmarks vs S2, Boost.Geometry, GeographicLib#14
Merged
Conversation
MrHerrn
requested changes
May 10, 2026
gistrec
added a commit
that referenced
this pull request
May 10, 2026
Address PR #14 review feedback (@MrHerrn): with native point/geometry types built fresh inside the benchmark loop, conversion overhead was being charged to each competitor's per-call cost, inflating the gap on ops like Boost.Geometry's path_length. Move every native-type build out of the timed region so the numbers reflect algorithmic cost only. bench_geographiclib's area / path_length intentionally keep the PolygonArea + AddPoint work in-loop: AddPoint *is* the per-vertex geodesic computation, and Compute() only adds the closing-edge contribution — pre-building outside the loop would measure a cached double read, not real work. Comment explains this. Refresh README.md and docs/benchmarks.md result tables and TL;DR to match the new picture: ties Boost.Geometry on distance / heading / path_length within noise; wins clearly on area; trails S2 on distance / path_length / contains algorithmically (S2 still pays lat/lng->S2Point conversion in real lat/lng workloads, which these algorithm-only numbers do not count). Install-size advantage of 130-900x is unchanged.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #14 +/- ##
=======================================
Coverage 98.19% 98.19%
=======================================
Files 20 20
Lines 499 499
Branches 88 88
=======================================
Hits 490 490
Misses 1 1
Partials 8 8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
MrHerrn
reviewed
May 11, 2026
3 tasks
Address PR #14 review feedback (@MrHerrn): with native point/geometry types built fresh inside the benchmark loop, conversion overhead was being charged to each competitor's per-call cost, inflating the gap on ops like Boost.Geometry's path_length. Move every native-type build out of the timed region so the numbers reflect algorithmic cost only. bench_geographiclib's area / path_length intentionally keep the PolygonArea + AddPoint work in-loop: AddPoint *is* the per-vertex geodesic computation, and Compute() only adds the closing-edge contribution — pre-building outside the loop would measure a cached double read, not real work. Comment explains this. Refresh README.md and docs/benchmarks.md result tables and TL;DR to match the new picture: ties Boost.Geometry on distance / heading / path_length within noise; wins clearly on area; trails S2 on distance / path_length / contains algorithmically (S2 still pays lat/lng->S2Point conversion in real lat/lng workloads, which these algorithm-only numbers do not count). Install-size advantage of 130-900x is unchanged.
… split smoke CI - benchmarks/common/constants.hpp + bench_polygon/bench_queries helpers in random_data.hpp; bench files use shared constants instead of hard-coding (40.0, -74.0, 5.0, 1000) per file. - Every BENCHMARK macro now ->Repetitions(5)->ReportAggregatesOnly(true). - regular_polygon() lng-sign fix: vertices are now actually CCW (positive signed_area in our convention). - queries_around() clamps lat/lng to valid domain. - benchmarks smoke-build moved to its own workflow with paths filter on benchmarks/** + CMakeLists.txt + the workflow file; removed redundant step from ci.yml (doc-only PRs no longer pay for it).
- docs/benchmarks.md: "Disk footprint" -> "Deployment footprint"; drop "fraction of the disk footprint" / "33 MB install" claims as headline arguments; lean on dependency-free + lat/lng-native + S2Point-native data as the technical criteria. TL;DR compressed to scannable bullets, bold rule applied strictly at ~5%, N/A rows unified, polygon-area footnote added, naive-haversine baseline disclaimer in distance commentary, PolygonArea apples-to-apples note added. - README.md: merged Features + Why-use into one list, deduped install boilerplate (single find_package block), added polygon example demonstrating contains/area/path_length/on_path, replaced std::boolalpha with inline ternaries, "about 36 KB across 4 headers". - docs/api.md: merged Conventions + Numerical notes; expanded with Earth model + Google Maps reference, thread safety, error handling (noexcept story, nullopt/extrapolate semantics), include strategy. Added on_path and angle_between examples; offset_origin round-trip + nullopt example; readable comments on distance/path_length/area examples; geodesic-defaults note at top of Polygon functions. - benchmarks/README.md: drop Competitors table and Methodology notes (already in docs/benchmarks.md); reduced to install + build + measure mechanics.
Owner
Author
|
Fixed, ready for re-review, @MrHerrn |
MrHerrn
approved these changes
May 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
benchmarks/directory with Google Benchmark micro-benchmarks for:distance_between;heading;contains;area;path_length.The benchmarks compare
geo-utils-cppagainst:Conversion policy is documented and normalized across libraries: streams of points are converted inside the timed loop (the realistic cost when the input is lat/lng), long-lived polygons are pre-built once outside the loop (matches the geofence-loaded-once-queried-many-times pattern).
Also adds disk-footprint measurement via
benchmarks/size/measure.sh. The script builds minimal consumer programs against each library and reports:Documentation changes:
docs/benchmarks.mdwith methodology, full results per operation, and a "when to use which library" guide;Headline numbers on Apple M1, clang 17,
-O2 -DNDEBUG:distance_between, showing zero header-only overhead;distance/headingwithin ~5% noise; ahead on every polygon operation;contains(depending on polygon size);distance,heading,area,path_length, and oncontainsagainst ~10-vertex polygons. S2 winscontainsfrom ~100 vertices onward via its bounding-rectangle prefilter — the documented caveat;geometrysubset alone;That makes
geo-utils-cpproughly 130× to 900× smaller, depending on the comparison target.Build / CI hygiene:
URL_HASH SHA256=...pinned for the Google Benchmark FetchContent;strtod(not the UB-on-bad-inputatof);measure.shpersists failed build logs tobuild-bench/size-logs/and reports failure status via a sentinel file (works correctly across command-substitution boundaries);find_package(s2 NAMES s2 S2)accepts both casings of the installed config file.Benchmarks are off by default via
GEO_UTILS_CPP_BUILD_BENCHMARKS=OFFand are not run in CI (would require S2 / Boost / GeographicLib installs). A small smoke-build job in CI compilesbench_geo_utilsandbench_naive(the dependency-free portion) so the benchmark plumbing can't bitrot silently.