Changeset 17752 in josm for trunk/src


Ignore:
Timestamp:
2021-04-12T00:16:06+02:00 (4 years ago)
Author:
simon04
Message:

see #20745 - Avoid heap allocations due to BBox in IPrimitive.getBBox

Cache and return an immutable bounding box.

37.75% in MapCSSTagCheckerPerformanceTest#testCity amount to BBox::new via IPrimitive.getBBox

Location:
trunk/src/org/openstreetmap/josm
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/BBox.java

    r17703 r17752  
    148148    public final void add(double x, double y) {
    149149        if (!Double.isNaN(x) && !Double.isNaN(y)) {
    150             xmin = Math.min(xmin, x);
    151             xmax = Math.max(xmax, x);
    152             ymin = Math.min(ymin, y);
    153             ymax = Math.max(ymax, y);
     150            set(Math.min(xmin, x), Math.max(xmax, x), Math.min(ymin, y), Math.max(ymax, y));
    154151        }
    155152    }
     
    161158    public final void add(BBox other) {
    162159        if (other.isValid()) {
    163             xmin = Math.min(xmin, other.xmin);
    164             xmax = Math.max(xmax, other.xmax);
    165             ymin = Math.min(ymin, other.ymin);
    166             ymax = Math.max(ymax, other.ymax);
    167         }
     160            set(Math.min(xmin, other.xmin), Math.max(xmax, other.xmax), Math.min(ymin, other.ymin), Math.max(ymax, other.ymax));
     161        }
     162    }
     163
     164    protected void set(double xmin, double xmax, double ymin, double ymax) {
     165        this.xmin = xmin;
     166        this.xmax = xmax;
     167        this.ymin = ymin;
     168        this.ymax = ymax;
    168169    }
    169170
     
    371372
    372373    @Override
    373     public int hashCode() {
     374    public final int hashCode() {
    374375        return Objects.hash(xmin, xmax, ymin, ymax);
    375376    }
    376377
    377378    @Override
    378     public boolean equals(Object o) {
     379    public final boolean equals(Object o) {
    379380        if (this == o) return true;
    380         if (o == null || getClass() != o.getClass()) return false;
     381        if (!(o instanceof BBox)) return false;
    381382        BBox b = (BBox) o;
    382383        return Double.compare(b.xmax, xmax) == 0 && Double.compare(b.ymax, ymax) == 0
     
    451452                LatLon.cDdFormatter.format(ymax));
    452453    }
     454
     455    /**
     456     * Returns an immutable version of this bbox, i.e., modifying calls throw an {@link UnsupportedOperationException}.
     457     * @return an immutable version of this bbox
     458     */
     459    BBox toImmutable() {
     460        return new Immutable(this);
     461    }
     462
     463    private static class Immutable extends BBox {
     464
     465        Immutable(BBox copy) {
     466            super(copy);
     467        }
     468
     469        @Override
     470        protected void set(double xmin, double xmax, double ymin, double ymax) {
     471            throw new UnsupportedOperationException();
     472        }
     473
     474        @Override
     475        BBox toImmutable() {
     476            return this;
     477        }
     478    }
    453479}
  • trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java

    r17749 r17752  
    466466    /**
    467467     * Fetches the bounding box of the primitive.
     468     * Since 17752, the returned bounding box might be immutable, i.e., modifying calls throw an {@link UnsupportedOperationException}.
    468469     * @return Bounding box of the object
    469470     * @since 13764
  • trunk/src/org/openstreetmap/josm/data/osm/Relation.java

    r17357 r17752  
    441441    @Override
    442442    public BBox getBBox() {
    443         if (getDataSet() != null && bbox != null)
    444             return new BBox(bbox); // use cached value
     443        if (getDataSet() != null && bbox != null) {
     444            return this.bbox; // use cached immutable value
     445        }
    445446
    446447        BBox box = new BBox();
    447448        addToBBox(box, new HashSet<PrimitiveId>());
    448         if (getDataSet() != null)
    449             setBBox(box); // set cache
    450         return new BBox(box);
     449        if (getDataSet() == null) {
     450            return box;
     451        }
     452        setBBox(box); // set cached immutable value
     453        return this.bbox;
    451454    }
    452455
    453456    private void setBBox(BBox bbox) {
    454         this.bbox = bbox;
     457        this.bbox = bbox == null ? null : bbox.toImmutable();
    455458    }
    456459
  • trunk/src/org/openstreetmap/josm/data/osm/Way.java

    r17357 r17752  
    586586            return new BBox(this);
    587587        if (bbox == null) {
    588             bbox = new BBox(this);
    589         }
    590         return new BBox(bbox);
     588            setBBox(new BBox(this));
     589        }
     590        return bbox;
    591591    }
    592592
     
    596596    }
    597597
     598    private void setBBox(BBox bbox) {
     599        this.bbox = bbox == null ? null : bbox.toImmutable();
     600    }
     601
    598602    @Override
    599603    public void updatePosition() {
    600         bbox = new BBox(this);
     604        setBBox(new BBox(this));
    601605        clearCachedStyle();
    602606    }
  • trunk/src/org/openstreetmap/josm/gui/io/UploadTextComponentValidator.java

    r17238 r17752  
    154154            this.area = primitives.stream()
    155155                    .map(IPrimitive::getBBox)
    156                     .reduce((b1, b2) -> {
     156                    .reduce(new BBox(), (b1, b2) -> {
    157157                        b1.add(b2);
    158158                        return b1;
    159                     }).map(BBox::area)
    160                     .orElse(Double.NaN);
     159                    }).area();
    161160            validate();
    162161        }
Note: See TracChangeset for help on using the changeset viewer.