Skip to content

Commit

Permalink
Cache reference diffstate values (#15561)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Legioth authored and Vaadin Code Review committed Jan 12, 2015
1 parent 65904ff commit 3f27e02
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions server/src/com/vaadin/server/LegacyCommunicationManager.java
Expand Up @@ -24,6 +24,7 @@
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;

Expand Down Expand Up @@ -81,6 +82,8 @@ protected VaadinSession getSession() {
return session;
}

private static final ConcurrentHashMap<Class<? extends SharedState>, JsonValue> referenceDiffStates = new ConcurrentHashMap<Class<? extends SharedState>, JsonValue>();

/**
* @deprecated As of 7.1. See #11411.
*/
Expand All @@ -96,17 +99,10 @@ public static JsonObject encodeState(ClientConnector connector,
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,
Expand All @@ -118,6 +114,21 @@ public static JsonObject encodeState(ClientConnector connector,
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
Expand Down

0 comments on commit 3f27e02

Please sign in to comment.