Skip to content

fix(logbook_position_control): simplifier la géométrie avant terra::buffer() (perf + mémoire) - #14

Closed
JulienLebranchu wants to merge 1 commit into
mainfrom
fix/logbook_position_control-buffer-performance
Closed

JulienLebranchu wants to merge 1 commit into
mainfrom
fix/logbook_position_control-buffer-performance

Conversation

@JulienLebranchu

Copy link
Copy Markdown
Contributor

Closes #13.

Problème

logbook_position_control() appelle terra::buffer() sur les polygones de mer/ports à chaque exécution, sans simplification préalable. Sur des géométries fusionnées (st_union() de plusieurs sous-zones côté application appelante), ça produit des polygones à 100k+ sommets, et le buffering de ces géométries domine à la fois le temps d'exécution et la mémoire native (hors segment géré par R, donc invisible à gc()).

Impact réel : ce coût est la cause directe des crashs OOM observés en production sur AkadoR (conteneurs ShinyProxy plafonnés à 1 Gio par session). Investigation complète : #13, et côté AkadoR akador-apps#49.

Correctif

Ajoute un paramètre simplify_tolerance (défaut : 50 m, très inférieur aux buffer_sea/buffer_harbour par défaut de 925 m / 11100 m), appliqué via sf::st_simplify() juste avant chaque appel terra::buffer() (mer + ports départ/arrivée). Mettre simplify_tolerance = 0 désactive la simplification (comportement historique).

Vérification

Sur données réelles de production (1130 activités, 49 marées, 6 mois) :

Avant Après
Temps 29.4 s 7.1 s (~4x)
Mémoire pic (RSS) ~792-908 Mio ~499 Mio
Résultat (report) — identical() == TRUE avec la version non corrigée

Le doctest existant (R/logbook_position_control.R / tests/testthat/test-doctest-logbook_position_control.R) passe sans modification — les géométries synthétiques du test sont trop petites pour que la simplification à 50 m ait le moindre effet.

Non inclus dans cette PR

La deuxième piste identifiée dans #13 (mettre en cache le buffer calculé plutôt que de le recalculer à chaque appel) impliquerait un changement d'API plus large ; je la laisse à l'appréciation des mainteneurs comme évolution future, discutée dans #13.

…() to cut runtime/memory

terra::buffer() on unsimplified sea/harbour polygons dominates both
runtime and native (off-R-heap) memory: measured 107s and ~800 MiB of
process RSS on real production data (1130 activities, 49 trips), for
buffered sea polygons reaching 110k-266k vertices after st_union().
That memory is invisible to gc() since it lives inside terra's
GDAL/GEOS structures, and it is the direct cause of OOM kills in
AkadoR/ShinyProxy sessions capped at 1 GiB (see #13 and
akador-apps#49 on forge.ird.fr for the full investigation).

Adds a `simplify_tolerance` parameter (default 50m, well below the
existing buffer_sea=925/buffer_harbour=11100 defaults) applied via
sf::st_simplify() before each terra::buffer() call. Set to 0 to
disable.

Verified on real data (1130 activities): ~4x faster (29.4s -> 7.1s),
peak memory ~792 MiB -> ~499 MiB, and output is bit-for-bit identical
(identical() == TRUE) to the unfixed version. Existing doctest
unchanged and passing.
@OceaneBouhineauIRD

Copy link
Copy Markdown
Collaborator

Bonjour Julien,
Je pense qu'il est plus pertinent de rajouter sf::st_simplify() au niveau d'AkadoR pour modifier directement la forme des océans, par ailleurs dans le commit il est proposé aussi de rajouter sf::st_simplify() juste avant les buffer des ports, mais je ne voit pas trop l'intérêt de simplifier un point.
J'attend de retrouver mes accès pour pouvoir testé l'ajout de sf::st_simplify() mais je ne suis pas sur de merge cette pull request dans Codama (la modification sera probablement déporter dans AkadoR)

@OceaneBouhineauIRD

Copy link
Copy Markdown
Collaborator

Je ferme cette issue, le patch sf::st_simplify() est implémenté directement dans AkadoR.
L'impact sur les données est minime avec dTolerance = 50, seuls 10 positions sont impactés (tous concerne des objets échoués)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants