While I was investigating a way to improve performance in JOSM (see https://josm.openstreetmap.de/ticket/23472 ), I saw that java.awt.geom.Area#intersect was taking a disproportionate amount of CPU cycles.

I was able to decrease the amount of time spent in `intersect` by doing bounds intersection checks prior to calling `intersect`.

Is there a reason why `intersect` doesn't look something like

|    public void intersect(Area rhs) {
        final var lhsBounds = this.getCachedBounds();
        final var rhsBounds = rhs.getCachedBounds();
        if (!lhsBounds.intersects(rhsBounds) || !this.intersects(rhsBounds) || !rhs.intersects(lhsBounds)) {
            curves = EmptyCurves;
        } else {
            curves = new AreaOp.IntOp().calculate(this.curves, rhs.curves);
        }
        invalidateBounds();
    }|

My /assumption/ is that it wasn't a method that has been extensively profiled, but it is entirely possible that there is something I don't know.


For reference, the bounds checking I did outside of the JDK looked like this (simplified -- see link above for actual code):

|    public static Area calculateIntersection(Area lhs, Area rhs) {
        final Rectangle lhsBounds = lhs.getBounds2d();
        final Rectangle rhsBounds = rhs.getBounds2d();
        if (!lhsBounds.intersects(rhsBounds) && !lhs.intersects(rhsBounds) && !rhs.intersects(lhsBounds)) {
            return new Area();
        }
        return lhs.intersect(rhs);
|

|    }|


For my specific use case, this lead to the following performance improvements in my test workload (CPU and memory allocations as measured by IntelliJ IDEA's profiler for the calling method):


        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%

Thanks,

Taylor

Reply via email to