Changeset 18464 in josm


Ignore:
Timestamp:
2022-06-06T16:04:20+02:00 (2 years ago)
Author:
taylor.smock
Message:

Extract equalsEpsilon from LatLon into ILatLon

This significantly reduces allocations from DataSetMerger#merge.
In testing, it went from ~400 MiB allocations to ~19 MiB allocations.

The allocations largely came from checking if two nodes had equal coordinates.
The code used LatLon#getCoor followed by equalsEpsilon, when all the
required information was already present in Node, but LatLon had the method.

As an additional enhancement, equalsEpsilon was somewhat generified, in that
there is an additional method where we can specify a different precision.

This fixes #22104, see #7159.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/coor/ILatLon.java

    r13173 r18464  
    1616 */
    1717public interface ILatLon {
     18    /**
     19     * Minimum difference in location to not be represented as the same position.
     20     * The API returns 7 decimals.
     21     */
     22    double MAX_SERVER_PRECISION = 1e-7;
    1823
    1924    /**
     
    5257        }
    5358    }
     59
     60    /**
     61     * Determines if the other point has almost the same lat/lon values.
     62     * @param other other lat/lon
     63     * @return <code>true</code> if the other point has almost the same lat/lon
     64     * values, only differing by no more than 1 / {@link #MAX_SERVER_PRECISION MAX_SERVER_PRECISION}.
     65     * @since 18464 (extracted from {@link LatLon})
     66     */
     67    default boolean equalsEpsilon(ILatLon other) {
     68        return equalsEpsilon(other, MAX_SERVER_PRECISION);
     69    }
     70
     71    /**
     72     * Determines if the other point has almost the same lat/lon values.
     73     * @param other other lat/lon
     74     * @param precision The precision to use
     75     * @return <code>true</code> if the other point has almost the same lat/lon
     76     * values, only differing by no more than 1 / precision.
     77     * @since 18464 (extracted from {@link LatLon})
     78     */
     79    default boolean equalsEpsilon(ILatLon other, double precision) {
     80        double p = precision / 2;
     81        return Math.abs(lat() - other.lat()) <= p && Math.abs(lon() - other.lon()) <= p;
     82    }
    5483}
  • trunk/src/org/openstreetmap/josm/data/coor/LatLon.java

    r17333 r18464  
    4646     * The API returns 7 decimals.
    4747     */
    48     public static final double MAX_SERVER_PRECISION = 1e-7;
     48    public static final double MAX_SERVER_PRECISION = ILatLon.MAX_SERVER_PRECISION;
    4949    /**
    5050     * The inverse of the server precision
     
    186186     * @return <code>true</code> if the other point has almost the same lat/lon
    187187     * values, only differing by no more than 1 / {@link #MAX_SERVER_PRECISION MAX_SERVER_PRECISION}.
    188      */
     188     * @deprecated since 18464 (use {@link ILatLon#equalsEpsilon(ILatLon)} instead)
     189     */
     190    @Deprecated
    189191    public boolean equalsEpsilon(LatLon other) {
    190         double p = MAX_SERVER_PRECISION / 2;
    191         return Math.abs(lat()-other.lat()) <= p && Math.abs(lon()-other.lon()) <= p;
     192        return ILatLon.super.equalsEpsilon(other);
    192193    }
    193194
  • trunk/src/org/openstreetmap/josm/data/osm/Node.java

    r16553 r18464  
    293293
    294294    private boolean hasEqualCoordinates(Node other) {
    295         final LatLon c1 = getCoor();
    296         final LatLon c2 = other.getCoor();
    297         return (c1 == null && c2 == null) || (c1 != null && c2 != null && c1.equalsEpsilon(c2));
     295        if (this.isLatLonKnown() && other.isLatLonKnown()) {
     296            return this.equalsEpsilon(other);
     297        }
     298        return false;
    298299    }
    299300
  • trunk/src/org/openstreetmap/josm/data/osm/NodePositionComparator.java

    r12161 r18464  
    1717    public int compare(Node n1, Node n2) {
    1818
    19         if (n1.getCoor().equalsEpsilon(n2.getCoor()))
     19        if (n1.equalsEpsilon(n2))
    2020            return 0;
    2121
  • trunk/test/unit/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandlerTest.java

    r17275 r18464  
    4949
    5050        transferHandler.pasteOn(target, null);
    51         assertTrue(n1.getCoor().equalsEpsilon(ds2.getNodes().iterator().next().getCoor()));
     51        assertTrue(n1.equalsEpsilon(ds2.getNodes().iterator().next()));
    5252
    5353        ds2.clear();
     
    5656        LatLon pos = new LatLon(55, -5);
    5757        transferHandler.pasteOn(target, ProjectionRegistry.getProjection().latlon2eastNorth(pos));
    58         assertTrue(pos.equalsEpsilon(ds2.getNodes().iterator().next().getCoor()));
     58        assertTrue(pos.equalsEpsilon(ds2.getNodes().iterator().next()));
    5959    }
    6060
  • trunk/test/unit/org/openstreetmap/josm/io/GeoJSONReaderTest.java

    r18037 r18464  
    167167        return (p1 instanceof Node)
    168168            && (p2 instanceof Node)
    169             && ((Node) p1).getCoor().equalsEpsilon(((Node) p2).getCoor());
     169            && ((Node) p1).equalsEpsilon(((Node) p2));
    170170    }
    171171
Note: See TracChangeset for help on using the changeset viewer.