Mik*_*Hay 4 java serialization jodatime
在我的机器上,以下代码段:
DateTime now = DateTime.now();
System.out.println(now);
System.out.println("Date size:\t\t"+serialiseToArray(now).length);
System.out.println("DateString size:\t"+serialiseToArray(now.toString()).length);
System.out.println("java.util.Date size:\t"+serialiseToArray(new Date()).length);
Duration twoHours = Duration.standardHours(2);
System.out.println(twoHours);
System.out.println("Duration size:\t\t"+serialiseToArray(twoHours).length);
System.out.println("DurationString size:\t"+serialiseToArray(twoHours.toString()).length);
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
2013-09-09T15:07:44.642+01:00
Date size: 273
DateString size: 36
java.util.Date size: 46
PT7200S
Duration size: 107
DurationString size: 14
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,org.joda.time.DateTime对象比它的String形式大5倍以上,它似乎完美地描述了它,并且java.util.Date等价.表示2小时的Duration对象也比我预期的要大得多,因为查看源它似乎唯一的成员变量是单个long
值.
为什么这些序列化对象如此之大?是否有任何预先存在的解决方案来获得更小的代表?
serialiseToArray方法,供参考:
private static byte[] serialiseToArray(Serializable s)
{
try
{
ByteArrayOutputStream byteArrayBuffer = new ByteArrayOutputStream();
new ObjectOutputStream(byteArrayBuffer).writeObject(s);
return byteArrayBuffer.toByteArray();
}
catch (IOException ex)
{
throw new RuntimeException(ex);
}
}
Run Code Online (Sandbox Code Playgroud)
序列化有一些开销.在这种情况下,您最常注意到的开销是在实际输出中描述了类结构.并且由于Duration
有一个基类(BaseDuration
)和两个接口(ReadableDuration
和Serializable
),这个开销变得略大于Date
(没有基类和单个接口).
这些类是使用序列化文件中的完全限定类名引用的,因此创建了相当多的字节.
好消息:每个输出流只支付一次开销.如果序列化另一个Duration
对象,则大小差异应该相当小.
我已经使用jdeserialize项目来查看序列化a java.util.Date
与a 的结果Duration
(请注意,此工具不需要访问.class
文件,因此它转储的所有信息实际上都包含在序列化数据中):
结果java.util.Date
如下:
read: java.util.Date _h0x7e0001 = r_0x7e0000; //// BEGIN stream content output java.util.Date _h0x7e0001 = r_0x7e0000; //// END stream content output //// BEGIN class declarations (excluding array classes) class java.util.Date implements java.io.Serializable { } //// END class declarations //// BEGIN instance dump [instance 0x7e0001: 0x7e0000/java.util.Date object annotations: java.util.Date [blockdata 0x00: 8 bytes] field data: 0x7e0000/java.util.Date: ] //// END instance dump
结果Duration
如下:
read: org.joda.time.Duration _h0x7e0002 = r_0x7e0000; //// BEGIN stream content output org.joda.time.Duration _h0x7e0002 = r_0x7e0000; //// END stream content output //// BEGIN class declarations (excluding array classes) class org.joda.time.Duration extends org.joda.time.base.BaseDuration implements java.io.Serializable { } class org.joda.time.base.BaseDuration implements java.io.Serializable { long iMillis; } //// END class declarations //// BEGIN instance dump [instance 0x7e0002: 0x7e0000/org.joda.time.Duration field data: 0x7e0001/org.joda.time.base.BaseDuration: iMillis: 0 0x7e0000/org.joda.time.Duration: ] //// END instance dump
请注意,"类声明"块的长度要长得多Duration
.这也解释了为什么序列化单个 Duration
需要107个字节,但序列化两个(不同的)Duration
对象只需要121个字节.