Reviewers: rdayal,
Message:
Also see the discussion on the bug, my last replied copied here for
convenience:
http://code.google.com/p/google-web-toolkit/issues/detail?id=6331
The thing is: JS cannot represent all long values, so if you want to
encode such value as a numeric in JSON, it means you have to give up
parsing JSON using native JS (JSON.parse wherever it's supported, eval()
otherwise) at the detriment of performance.
The questions now are:
- the impact on performances of supporting both numerics and strings as
input (I suspect it would be minimal, as there's already code to support
several string formats)
- whether to serialize to a numeric whenever it's possible (it will
always be when the value comes from JS, and will generally be the case
anyway unless you try to send a Date in the very far past or future).
And because this would be a breaking change in the "protocol" (you'd
have to change the "receiving part" at the same time as the "sending"
part) I'm not sure it'd be OK. That part could be deferred a bit though,
to let in-production apps the time to update their "receivers" before
the "senders" are updated to send numerics. Serializing to numerics, on
the other hand, would boost performances, so it might be worth it.
Description:
Issue 6331: Let AutoBean serialize dates as numbers when possible.
Most dates' timestamp can be expressed as a double or JS Number, so
let's do so instead of using a String, which involves the Long overhead
in GWT-JS client side. Let's just hope the GWT compiler can optimise out
the double-cast (from double to long inside Date#getTime() emulation,
and from long back to double in ValueCodex).
The alternative would be to refuse sending dates whose timestamp cannot
be expressed as a double/JS Number (actually, a JS date's value space is
even smaller than that: not all Number values are accepted as a Date
timestamp; so it's already implicitly the case when the client is
GWT-compiled JS); that would remove the overhead of the check for the
overflow of the double's value space when serializing.
Please review this at http://gwt-code-reviews.appspot.com/1601805/
Affected files:
M user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
Index: user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
diff --git
a/user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
b/user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
index
a08a57d735756d0e5db62397b37ed80de03832e3..a29cbb0f8b065516ac620c91a4e100e1c1c0b95c
100644
--- a/user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
+++ b/user/src/com/google/web/bindery/autobean/shared/ValueCodex.java
@@ -103,12 +103,20 @@ public class ValueCodex {
@Override
public Date decode(Class<?> clazz, Splittable value) {
+ if (value.isNumber()) {
+ return new Date((long) value.asNumber());
+ }
return StringQuoter.tryParseDate(value.asString());
}
@Override
public Splittable encode(Object value) {
- return StringQuoter.create(String.valueOf(((Date)
value).getTime()));
+ long timestamp = ((Date) value).getTime();
+ // If value can be represented as double (which will always be the
case in JavaScript), then use it for the serialization, otherwise use a
String.
+ if ((Double.MIN_VALUE <= timestamp) && (timestamp <=
Double.MAX_VALUE)) {
+ return StringQuoter.create((double) timestamp);
+ }
+ return StringQuoter.create(String.valueOf(timestamp));
}
},
DOUBLE(Double.class, double.class, 0d) {
@@ -357,7 +365,7 @@ public class ValueCodex {
* May return <code>null</code>.
*/
private static <T> Type findType(Class<T> clazz) {
- if (clazz.isEnum() || (clazz.getSuperclass() != null &&
clazz.getSuperclass().isEnum())) {
+ if (clazz.isEnum()) {
return Type.ENUM;
}
return TYPES_BY_CLASS.get(clazz);
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors