]> source.dussan.org Git - vaadin-framework.git/commitdiff
Cache reference diffstate values (#15561)
authorLeif Åstrand <leif@vaadin.com>
Sat, 10 Jan 2015 11:36:51 +0000 (13:36 +0200)
committerVaadin Code Review <review@vaadin.com>
Mon, 12 Jan 2015 08:24:53 +0000 (08:24 +0000)
Benchmarked with the "Set 40 panels as content" action in
BasicPerformanceTest. This is really a worst case scenario since it
doesn't do anything else than create lots of components, whereas more
common use cases would spend more time updating existing components or
executing business logic instead.

Without this patch, each action spent about 6 ms creating reference
diffstate values, making up about 20% of the total processing time. With
the patch applied, the time (including the new map lookup) was reduced
to around 0.2 ms and the total processing time was also reduced
accordingly.

Change-Id: If22a73b591b87793c78cb360bcfa8e030f003730

server/src/com/vaadin/server/LegacyCommunicationManager.java

index 485084b515df4dc416f9403a30d1852bf853f09a..fda5ad444f80138a5fb7c6a523e11ebcdc625842 100644 (file)
@@ -24,6 +24,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -81,6 +82,8 @@ public class LegacyCommunicationManager implements Serializable {
         return session;
     }
 
+    private static final ConcurrentHashMap<Class<? extends SharedState>, JsonValue> referenceDiffStates = new ConcurrentHashMap<Class<? extends SharedState>, JsonValue>();
+
     /**
      * @deprecated As of 7.1. See #11411.
      */
@@ -96,17 +99,10 @@ public class LegacyCommunicationManager implements Serializable {
         if (diffState == null && supportsDiffState) {
             // Use an empty state object as reference for full
             // repaints
-
-            try {
-                SharedState referenceState = stateType.newInstance();
-                EncodeResult encodeResult = JsonCodec.encode(referenceState,
-                        null, stateType, uI.getConnectorTracker());
-                diffState = encodeResult.getEncodedValue();
-            } catch (Exception e) {
-                getLogger()
-                        .log(Level.WARNING,
-                                "Error creating reference object for state of type {0}",
-                                stateType.getName());
+            diffState = referenceDiffStates.get(stateType);
+            if (diffState == null) {
+                diffState = createReferenceDiffStateState(stateType);
+                referenceDiffStates.put(stateType, diffState);
             }
         }
         EncodeResult encodeResult = JsonCodec.encode(state, diffState,
@@ -118,6 +114,21 @@ public class LegacyCommunicationManager implements Serializable {
         return (JsonObject) encodeResult.getDiff();
     }
 
+    private static JsonValue createReferenceDiffStateState(
+            Class<? extends SharedState> stateType) {
+        try {
+            SharedState referenceState = stateType.newInstance();
+            EncodeResult encodeResult = JsonCodec.encode(referenceState, null,
+                    stateType, null);
+            return encodeResult.getEncodedValue();
+        } catch (Exception e) {
+            getLogger().log(Level.WARNING,
+                    "Error creating reference object for state of type {0}",
+                    stateType.getName());
+            return null;
+        }
+    }
+
     /**
      * Resolves a dependency URI, registering the URI with this
      * {@code LegacyCommunicationManager} if needed and returns a fully