summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Lange <lange.fabian@gmail.com>2014-04-03 22:35:51 +0200
committerFabian Lange <lange.fabian@gmail.com>2014-04-09 11:47:21 +0200
commit52db8e5457e1afcb56a5047adbddf15c44754e8c (patch)
tree4af8ba00cb3ca2a1dd751e89a34aec7071bb4ae4
parent3edf6bd933804413094aca2cd678a0f58369d7d0 (diff)
downloadvaadin-framework-52db8e5457e1afcb56a5047adbddf15c44754e8c.tar.gz
vaadin-framework-52db8e5457e1afcb56a5047adbddf15c44754e8c.zip
Optimizes memory and CPU usage in JSONCodec (#13545)
The null element and the empty JSONArray are frequently created and used as temporary objects to be encoded by the json encoder. Because they are never manipulated it is possible to reuse the same empty element again and save a significant amount of temp objects. This also helps jsonEquals, which then can return faster due to: if (fieldValue == referenceValue) return true jsonEquals does not need to check the referenceValue for JSONobject.NULL. The invoking code makes sure this never happens. Boolean and Integer values are very often and much more efficiently compared directly instead of using toString. Change-Id: I5fd736427019406469357cda1115d2683b7a5e2b
-rw-r--r--server/src/com/vaadin/server/JsonCodec.java38
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java1
2 files changed, 29 insertions, 10 deletions
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java
index d05922b40d..d5e1082487 100644
--- a/server/src/com/vaadin/server/JsonCodec.java
+++ b/server/src/com/vaadin/server/JsonCodec.java
@@ -62,6 +62,25 @@ import com.vaadin.ui.ConnectorTracker;
*/
public class JsonCodec implements Serializable {
+ /* Immutable Encode Result representing null */
+ private static final EncodeResult ENCODE_RESULT_NULL = new EncodeResult(
+ JSONObject.NULL);
+
+ /* Immutable empty JSONArray */
+ private static final JSONArray EMPTY_JSON_ARRAY = new JSONArray() {
+ @Override
+ public JSONArray put(Object value) {
+ throw new UnsupportedOperationException(
+ "Immutable empty JSONArray.");
+ };
+
+ @Override
+ public JSONArray put(int index, Object value) {
+ throw new UnsupportedOperationException(
+ "Immutable empty JSONArray.");
+ };
+ };
+
public static interface BeanProperty extends Serializable {
public Object getValue(Object bean) throws Exception;
@@ -635,7 +654,7 @@ public class JsonCodec implements Serializable {
}
if (null == value) {
- return encodeNull();
+ return ENCODE_RESULT_NULL;
}
if (value instanceof String[]) {
@@ -680,7 +699,7 @@ public class JsonCodec implements Serializable {
if (value instanceof Component
&& !(LegacyCommunicationManager
.isComponentVisibleToClient((Component) value))) {
- return encodeNull();
+ return ENCODE_RESULT_NULL;
}
return new EncodeResult(connector.getConnectorId());
} else if (value instanceof Enum) {
@@ -701,10 +720,6 @@ public class JsonCodec implements Serializable {
}
}
- private static EncodeResult encodeNull() {
- return new EncodeResult(JSONObject.NULL);
- }
-
public static Collection<BeanProperty> getProperties(Class<?> type)
throws IntrospectionException {
Collection<BeanProperty> cachedProperties = typePropertyCache.get(type);
@@ -781,14 +796,17 @@ public class JsonCodec implements Serializable {
if (fieldValue == JSONObject.NULL) {
fieldValue = null;
}
- if (referenceValue == JSONObject.NULL) {
- referenceValue = null;
- }
if (fieldValue == referenceValue) {
return true;
} else if (fieldValue == null || referenceValue == null) {
return false;
+ } else if (fieldValue instanceof Integer
+ && referenceValue instanceof Integer) {
+ return ((Integer) fieldValue).equals(referenceValue);
+ } else if (fieldValue instanceof Boolean
+ && referenceValue instanceof Boolean) {
+ return ((Boolean) fieldValue).equals(referenceValue);
} else {
return fieldValue.toString().equals(referenceValue.toString());
}
@@ -849,7 +867,7 @@ public class JsonCodec implements Serializable {
if (map.isEmpty()) {
// Client -> server encodes empty map as an empty array because of
// #8906. Do the same for server -> client to maintain symmetry.
- return new JSONArray();
+ return EMPTY_JSON_ARRAY;
}
if (keyType == String.class) {
diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
index 0a36c7f7ce..e938a1cd37 100644
--- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
+++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java
@@ -63,6 +63,7 @@ public class TestClassesSerializable extends TestCase {
"com\\.vaadin\\.sass.*", //
"com\\.vaadin\\.testbench.*", //
"com\\.vaadin\\.util\\.CurrentInstance\\$1", //
+ "com\\.vaadin\\.server\\.JsonCodec\\$1", //
"com\\.vaadin\\.server\\.communication\\.PushConnection", //
"com\\.vaadin\\.server\\.communication\\.AtmospherePushConnection", //
"com\\.vaadin\\.util\\.ConnectorHelper", //