Highlights
Patch bump. pypatchworkpp.patchworkpp is now +14.8% Hz on KITTI seq 00 (97.5 → 111.9 Hz, median of 3 runs, i7-12700) thanks to killing short-lived heap allocations in R-VPF + R-GPF. Closes the alloc-driven part of #96.
Perf — pypatchworkpp.patchworkpp
KITTI seq 00, 2900 timed frames, median of 3 runs:
| Stage | ms/frame | Hz | Δ Hz |
|---|---|---|---|
| v1.4.0 baseline (JacobiSVD + per-call allocs) | 10.26 | 97.5 | — |
| eigh only | 9.94 | 100.6 | +3.2% |
| v1.4.1 (eigh + alloc-free) | 8.94 | 111.9 | +14.8% |
The win comes from three changes inside PatchWorkpp::extract_piecewiseground and PatchWorkpp::estimate_plane:
estimate_plane: dropEigen::MatrixX3f eigen_ground,centered, andcentered.adjoint() * centeredheap allocations. Replace with a single-pass scalar accumulation of mean + 9 cross-products; build the 3×3 cov on the stack.extract_piecewiseground: promotesrc_wo_verticalsandsrc_tmpto reused instance scratch members.vector::clear()keeps capacity, so per-patch malloc pressure on the glibc heap drops away after the first few patches.estimateGroundmain loop:auto& zoneinstead ofauto zoneforConcentricZoneModel_[zone_idx]. Avoids a deep-copy of the full 3-level nested vector per outer iteration.
Plus a smaller cleanup: JacobiSVD<Matrix3f> → SelfAdjointEigenSolver::computeDirect on the 3×3 PSD covariance in both cpp/common/src/plane_fit.cpp and the in-place PatchWorkpp::estimate_plane. singular_values_ is repacked descending so every consumer (linearity_, planarity_, ground_flatness, line_variable, flatness_thr index (2)) keeps the same convention bit-for-bit.
Patchwork (classic)
Unchanged: 4.29 ms / 232.9 Hz (within run-to-run noise of the v1.4.0 baseline). TBB parallel_for already amortises allocations across cores and SVD is sub-µs/patch.
Numerical equivalence
KITTI seq 00 (4541 frames), v1.4.0 → v1.4.1:
| Method (protocol) | Before | After | Δ F1 |
|---|---|---|---|
patchwork (pw) |
P 92.34, R 94.64, F1 93.41 | P 92.34, R 94.64, F1 93.41 | 0.00 |
patchworkpp (pp) |
P 94.88, R 98.47, F1 96.62 | P 94.89, R 98.48, F1 96.63 | +0.01 |
Algebraic identity of JacobiSVD vs eigh verified on 500 real KITTI patch covariances: normal_ (up to sign), singular_values_, linearity_, planarity_, ground_flatness, line_variable all match to FP precision.