﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
22139	[PATCH] Significantly reduce allocations in NodeElement and StyledMapRenderer	taylor.smock	team	"{{{#!diff
diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
index b27acb4bc5..2e49c30ca5 100644
--- a/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
+++ b/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
@@ -52,6 +52,7 @@ import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.IRelation;
 import org.openstreetmap.josm.data.osm.IRelationMember;
 import org.openstreetmap.josm.data.osm.IWay;
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmData;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
@@ -754,7 +755,9 @@ public class StyledMapRenderer extends AbstractMapRenderer {
         if (size <= 0 && !n.isHighlighted())
             return;
 
-        MapViewPoint p = mapState.getPointFor(n);
+        // This reduces memory usage for StyledMapRenderer#paintWithLock from 5.1% to 1.2%
+        // and slightly reduces CPU usage.
+        MapViewPoint p = n instanceof Node ? mapState.getPointFor((Node) n) : mapState.getPointFor(n);
 
         if (n.isHighlighted()) {
             drawPointHighlight(p.getInView(), size);
diff --git a/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java b/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
index 69b05c84b6..2b6852d7ba 100644
--- a/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
+++ b/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
@@ -7,7 +7,6 @@ import java.awt.Rectangle;
 import java.awt.Stroke;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.stream.IntStream;
 
 import org.openstreetmap.josm.data.osm.INode;
 import org.openstreetmap.josm.data.osm.IPrimitive;
@@ -350,8 +349,14 @@ public class NodeElement extends StyleElement {
         }
     }
 
-    private static int max(int... elements) {
-        return IntStream.of(elements).max().orElseThrow(IllegalStateException::new);
+    private static int max(int a, int b, int c, int d) {
+        // Profile before switching to a stream/int[] array
+        // This was 66% give or take for painting nodes in terms of memory allocations
+        // and was ~17% of the CPU allocations. By not using a vararg method call, we avoid
+        // the creation of an array. By avoiding both streams and arrays, the cost for this method is negligible.
+        // This means that this saves about 7% of the CPU cycles during map paint, and about 20%
+        // of the memory allocations during map paint.
+        return Math.max(a, Math.max(b, Math.max(c, d)));
     }
 
     @Override
}}}"	defect	new	normal	22.06	Core			performance	
