Opened 11 months ago

Last modified 10 months ago

#23472 closed enhancement

[PATCH] Decrease cost of Geometry#polygonIntersectionResult (specifically for geometry.mapcss) — at Initial Version

Reported by: taylor.smock Owned by: taylor.smock
Priority: normal Milestone: 24.02
Component: Core Version:
Keywords: performance Cc:

Description

When profiling the validator with an overpass download of Mesa County, Colorado, ~50% of the total CPU time are taken up by Geometry#polygonIntersectionResult. With the attached patch, the total CPU time for that method are reduced to ~7% of the total CPU cycles.

Specific measurements:

CPUMemory AllocationsTime
No patch 522,778ms 54.13 GB ~840s
Patch 22,581ms 1.13 GB ~210s
Difference -500,197ms -53 GB -630s
Difference % -95.7% -97.9% -77.7%
  • src/org/openstreetmap/josm/tools/Geometry.java

    diff --git a/src/org/openstreetmap/josm/tools/Geometry.java b/src/org/openstreetmap/josm/tools/Geometry.java
    a b  
    693693     * @since 15938
    694694     */
    695695    public static Pair<PolygonIntersection, Area> polygonIntersectionResult(Area a1, Area a2, double eps) {
     696        // Simple intersect check (if their bounds don't intersect, don't bother going further; there will be no intersection)
     697        // This avoids the more expensive Area#intersect call some of the time (decreases CPU and memory allocation by ~95%)
     698        // in Mesa County, CO geometry validator test runs.
     699        final Rectangle2D a12d = a1.getBounds2D();
     700        final Rectangle2D a22d = a2.getBounds2D();
     701        if (!a12d.intersects(a22d) || !a1.intersects(a22d) || !a2.intersects(a12d)) {
     702            return new Pair<>(PolygonIntersection.OUTSIDE, new Area());
     703        }
    696704        Area inter = new Area(a1);
    697705        inter.intersect(a2);
    698706
    699707        if (inter.isEmpty() || !checkIntersection(inter, eps)) {
    700708            return new Pair<>(PolygonIntersection.OUTSIDE, inter);
    701         } else if (a2.getBounds2D().contains(a1.getBounds2D()) && inter.equals(a1)) {
     709        } else if (a22d.contains(a12d) && inter.equals(a1)) {
    702710            return new Pair<>(PolygonIntersection.FIRST_INSIDE_SECOND, inter);
    703         } else if (a1.getBounds2D().contains(a2.getBounds2D()) && inter.equals(a2)) {
     711        } else if (a12d.contains(a22d) && inter.equals(a2)) {
    704712            return new Pair<>(PolygonIntersection.SECOND_INSIDE_FIRST, inter);
    705713        } else {
    706714            return new Pair<>(PolygonIntersection.CROSSING, inter);

Change History (0)

Note: See TracTickets for help on using tickets.