<!DOCTYPE html>
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>While I was investigating a way to improve performance in JOSM
      (see <a class="moz-txt-link-freetext" href="https://josm.openstreetmap.de/ticket/23472">https://josm.openstreetmap.de/ticket/23472</a> ), I saw that
      java.awt.geom.Area#intersect was taking a disproportionate amount
      of CPU cycles.</p>
    <p>I was able to decrease the amount of time spent in `intersect` by
      doing bounds intersection checks prior to calling `intersect`.</p>
    <p>Is there a reason why `intersect` doesn't look something like</p>
    <p><code>    public void intersect(Area rhs) {<br>
                final var lhsBounds = this.getCachedBounds();<br>
                final var rhsBounds = rhs.getCachedBounds();<br>
                if (!lhsBounds.intersects(rhsBounds) ||
        !this.intersects(rhsBounds) || !rhs.intersects(lhsBounds)) {<br>
                    curves = EmptyCurves;<br>
                } else {<br>
                    curves = new AreaOp.IntOp().calculate(this.curves,
        rhs.curves);<br>
                }<br>
                invalidateBounds();<br>
            }</code><br>
    </p>
    <p>My <i>assumption</i> 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.<br>
    </p>
    <p><br>
    </p>
    <p>For reference, the bounds checking I did outside of the JDK
      looked like this (simplified -- see link above for actual code):</p>
    <code>    public static Area calculateIntersection(Area lhs, Area
      rhs) {<br>
              final Rectangle lhsBounds = lhs.getBounds2d();<br>
              final Rectangle rhsBounds = rhs.getBounds2d();<br>
              if (!lhsBounds.intersects(rhsBounds) &&
      !lhs.intersects(rhsBounds) && !rhs.intersects(lhsBounds))
      {<br>
                  return new Area();<br>
              }<br>
              return lhs.intersect(rhs);<br>
    </code>
    <p><code>    }</code></p>
    <p><br>
    </p>
    <p>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):</p>
    <table class="wiki">
      <tbody>
        <tr>
          <td><br>
          </td>
          <th>CPU</th>
          <th>Memory Allocations</th>
          <th>Total Validator Time
          </th>
        </tr>
        <tr>
          <th>No patch</th>
          <td style="text-align: right"> 522,778ms</td>
          <td style="text-align: right"> 54.13 GB</td>
          <td style="text-align: right"> ~840s
          </td>
        </tr>
        <tr>
          <th>Patch</th>
          <td style="text-align: right"> 22,581ms</td>
          <td style="text-align: right"> 1.13 GB</td>
          <td style="text-align: right"> ~210s
          </td>
        </tr>
        <tr>
          <th>Difference</th>
          <td style="text-align: right"> -500,197ms</td>
          <td style="text-align: right"> -53 GB</td>
          <td style="text-align: right"> -630s
          </td>
        </tr>
        <tr>
          <th>Difference %</th>
          <td style="text-align: right"> -95.7%</td>
          <td style="text-align: right"> -97.9%</td>
          <td style="text-align: right"> -77.7%
          </td>
        </tr>
      </tbody>
    </table>
    <p></p>
    <p>Thanks,</p>
    <p>Taylor<br>
    </p>
  </body>
</html>