﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
23472	[PATCH] Decrease cost of Geometry#polygonIntersectionResult (specifically for geometry.mapcss)	taylor.smock	taylor.smock	"When profiling the validator with an overpass download of [https://www.openstreetmap.org/relation/1411341 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:
|| ||=CPU=||=Memory Allocations=||=Total Validator Time=||
||=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%||

{{{#!diff
Index: 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/src/org/openstreetmap/josm/tools/Geometry.java	(revision 18972)
+++ b/src/org/openstreetmap/josm/tools/Geometry.java	(date 1707840972516)
@@ -693,14 +693,22 @@
      * @since 15938
      */
     public static Pair<PolygonIntersection, Area> polygonIntersectionResult(Area a1, Area a2, double eps) {
+        // Simple intersect check (if their bounds don't intersect, don't bother going further; there will be no intersection)
+        // This avoids the more expensive Area#intersect call some of the time (decreases CPU and memory allocation by ~95%)
+        // in Mesa County, CO geometry validator test runs.
+        final Rectangle2D a12d = a1.getBounds2D();
+        final Rectangle2D a22d = a2.getBounds2D();
+        if (!a12d.intersects(a22d) || !a1.intersects(a22d) || !a2.intersects(a12d)) {
+            return new Pair<>(PolygonIntersection.OUTSIDE, new Area());
+        }
         Area inter = new Area(a1);
         inter.intersect(a2);
 
         if (inter.isEmpty() || !checkIntersection(inter, eps)) {
             return new Pair<>(PolygonIntersection.OUTSIDE, inter);
-        } else if (a2.getBounds2D().contains(a1.getBounds2D()) && inter.equals(a1)) {
+        } else if (a22d.contains(a12d) && inter.equals(a1)) {
             return new Pair<>(PolygonIntersection.FIRST_INSIDE_SECOND, inter);
-        } else if (a1.getBounds2D().contains(a2.getBounds2D()) && inter.equals(a2)) {
+        } else if (a12d.contains(a22d) && inter.equals(a2)) {
             return new Pair<>(PolygonIntersection.SECOND_INSIDE_FIRST, inter);
         } else {
             return new Pair<>(PolygonIntersection.CROSSING, inter);
}}}"	enhancement	closed	normal	24.02	Core		fixed	performance	
