AMF Serialization (followup Faster Serialization)
While i was looking for the fastest possible way to serialize Java Objects to byte-streams, i was comparing some serialization libs. With the help of Adobe Evangelist Cornel Creanga, i added AMF3 Serialization to the test.
Good things first: for my test-case, AMF3 turns out to be slightly faster and a little more compact than plain JDK6.
PlainSerializer: 999ms (Size: 639241 bytes) PlainSerializer: 862ms (Size: 639241 bytes) PlainSerializer: 779ms (Size: 639241 bytes) PlainSerializer: 781ms (Size: 639241 bytes) AMFSerializer: 775ms (Size: 554323 bytes) AMFSerializer: 680ms (Size: 554323 bytes) AMFSerializer: 661ms (Size: 554323 bytes) AMFSerializer: 656ms (Size: 554323 bytes)
This would be a good reason to use it if it was not for the following disadvantages:
- You need the to be serialized classes to be public.
- They need to have a no-arg Constructor being public as well.
- You have to expose the complete State of the Object by Getters/Setters
While the first two might be bearable, the third is a no-go. As AMF3 does not seem to look at the fields, a transient field will be serialized as well and if you missed a getter… well you know…
If you have dedicated Transfer Objects, that were just made for AMF3 Serialization, this might be fine. For me, the price to pay is way too high in comparison to about 10% performance improvement.
I am wondering, why the heck they tried to focus on properties instead of fields. As they call it Serialization, it´d be reasonable, to reflect the object´s complete state instead of its published properties. In fact, it would be even easier to reflect the Type-info etc. from fields instead of properties.


If you are always looking possible solutions for this problem, maybe you can look at :
http://wiki.tangosol.com/pages/viewpage.action?pageId=1343618
I’m currently making tests with their solution for my needs.
while it sounds interesting, i´d need to be a proud owner of a coherence license, right?
For the moment, i’m doing some tests.
But you’re right :
LICENSE RIGHTS
We grant you a nonexclusive, nontransferable limited license to use the programs only for the purpose of developing, testing, prototyping and demonstrating your application, and not for any other purpose. If you use the application you develop under this license for any internal data processing or for any commercial or production purposes, or you want to use the programs for any purpose other than as permitted under this agreement, you must obtain a production release version of the program by contacting us or an Oracle reseller to obtain the appropriate license. You acknowledge that we may not produce a production release version of the program and any development efforts undertaken by you are at your own risk. We may audit your use of the programs. Program documentation, if available, may accessed online at http://otn.oracle.com/docs.
sadly, i´ll not be provided with the necessary monetary resources, just for the sake of serialization.
Yes me too … But it can usefull when serialization is critical, as it could be in financial company for example.
You have to test java kryo.
http://code.google.com/p/kryo/
Performance are better, and it’s free
thanks for pointing me to it.
even if i preregister all classes involved (which is not possible in my usecase), the performance as well as size is way less than impressive:
PlainSerializer: 1097ms (Size: 699312 bytes)
PlainSerializer: 1045ms (Size: 699312 bytes)
PlainSerializer: 1028ms (Size: 699312 bytes)
PlainSerializer: 1024ms (Size: 699312 bytes)
PlainGZipSerializer: 1425ms (Size: 306747 bytes)
PlainGZipSerializer: 1429ms (Size: 306747 bytes)
PlainGZipSerializer: 1419ms (Size: 306747 bytes)
PlainGZipSerializer: 1415ms (Size: 306747 bytes)
[GC 139776K->13496K(506816K), 0.0306478 secs]
KryoSerializer: 1404ms (Size: 1648909 bytes)
KryoSerializer: 1818ms (Size: 1648909 bytes)
[GC 150014K->3265K(506816K), 0.0071186 secs]
KryoSerializer: 1762ms (Size: 1648909 bytes)
[GC 143041K->14697K(506816K), 0.0179855 secs]
KryoSerializer: 1339ms (Size: 1648909 bytes)
looks like there are a bunch of in-transit objects being created and collected. apart from that, Kryo does not work without no-arg constructors.
but the real showstopper in fact is: it does not seem to recognize duplicate references, so that plain serialization with just 700k is much more attractive than using kyro that turns the data (just lists, maps and strings) into 1.6mb.
not appealing.
really wonder how these guys do their benchmarks…
Actually, for my needs, Kryo performances are better (for size and time consuming) than all other serializer i used for tests.
But my scenario is very simple, small simples beans, which i can preregister and without cycles.
For example, here is my results for execution with 4 threads (for a 4-core processor)
Plain : 3551 bytes
Gzip Plain : 1333 bytes
[Norm-deserializeWithCompression ] Call(s): 4001, Total(ms): 1245, Avg(ms): 0.312, Median(ms): 0.283, Max(ms): 7.62, Min(ms): 0.265
[Norm-deserializeWithoutCompression ] Call(s): 4001, Total(ms): 1067, Avg(ms): 0.267, Median(ms): 0.237, Max(ms): 16.11, Min(ms): 0.222
[Norm-serializeWithCompression ] Call(s): 4016, Total(ms): 1085, Avg(ms): 0.271, Median(ms): 0.262, Max(ms): 5.90, Min(ms): 0.221
[Norm-serializeWithoutCompression ] Call(s): 4016, Total(ms): 389, Avg(ms): 0.097, Median(ms): 0.088, Max(ms): 6.45, Min(ms): 0.082
Hessian : 2001 bytes
Gzip Hessian : 871 bytes
[Hess-deserializeWithCompression ] Call(s): 4001, Total(ms): 747, Avg(ms): 0.187, Median(ms): 0.177, Max(ms): 6.97, Min(ms): 0.160
[Hess-deserializeWithoutCompression ] Call(s): 4001, Total(ms): 612, Avg(ms): 0.153, Median(ms): 0.146, Max(ms): 3.24, Min(ms): 0.130
[Hess-serializeWithCompression ] Call(s): 4016, Total(ms): 640, Avg(ms): 0.160, Median(ms): 0.158, Max(ms): 3.76, Min(ms): 0.118
[Hess-serializeWithoutCompression ] Call(s): 4016, Total(ms): 189, Avg(ms): 0.047, Median(ms): 0.040, Max(ms): 2.65, Min(ms): 0.036
Json : 1839 bytes
Gzip json : 707 bytes
[JSon-deserializeWithCompression ] Call(s): 4001, Total(ms): 347, Avg(ms): 0.087, Median(ms): 0.070, Max(ms): 8.75, Min(ms): 0.061
[JSon-deserializeWithoutCompression ] Call(s): 4001, Total(ms): 211, Avg(ms): 0.053, Median(ms): 0.038, Max(ms): 8.81, Min(ms): 0.035
[JSon-serializeWithCompression ] Call(s): 4016, Total(ms): 567, Avg(ms): 0.142, Median(ms): 0.139, Max(ms): 3.84, Min(ms): 0.101
[JSon-serializeWithoutCompression ] Call(s): 4016, Total(ms): 176, Avg(ms): 0.044, Median(ms): 0.032, Max(ms): 13.73, Min(ms): 0.028
XmlBean : 1078 bytes
Gzip XmlBean : 511 bytes
[XmlB-deserializeWithCompression ] Call(s): 4001, Total(ms): 362, Avg(ms): 0.091, Median(ms): 0.078, Max(ms): 5.20, Min(ms): 0.070
[XmlB-deserializeWithoutCompression ] Call(s): 4001, Total(ms): 263, Avg(ms): 0.066, Median(ms): 0.053, Max(ms): 4.12, Min(ms): 0.049
[XmlB-serializeWithCompression ] Call(s): 4016, Total(ms): 689, Avg(ms): 0.172, Median(ms): 0.137, Max(ms): 33.76, Min(ms): 0.096
[XmlB-serializeWithoutCompression ] Call(s): 4016, Total(ms): 259, Avg(ms): 0.065, Median(ms): 0.043, Max(ms): 30.57, Min(ms): 0.037
Kryo : 761 bytes
Gzip Kryo : 371 bytes
[Kryo-deserializeWithCompression ] Call(s): 4001, Total(ms): 190, Avg(ms): 0.047, Median(ms): 0.043, Max(ms): 4.22, Min(ms): 0.036
[Kryo-deserializeWithoutCompression ] Call(s): 4001, Total(ms): 106, Avg(ms): 0.026, Median(ms): 0.021, Max(ms): 4.39, Min(ms): 0.019
[Kryo-serializeWithCompression ] Call(s): 4016, Total(ms): 395, Avg(ms): 0.099, Median(ms): 0.099, Max(ms): 3.68, Min(ms): 0.065
[Kryo-serializeWithoutCompression ] Call(s): 4016, Total(ms): 89, Avg(ms): 0.022, Median(ms): 0.020, Max(ms): 3.22, Min(ms): 0.017
thanks for sharing. the cycle issue though is a showstopper for me.
I forgot to specify that i used Jackson for Json
[...] It is better to use a framework like Kryo, which provides much better performance EDIT: There seem to be some issues with Kryo: mainly, (1) objects appearing multiple times in the object graph are serialized once for every occurence and (2) Kryo requires a no-args constructor to be present in the class (see this blog post). [...]
Thanks for telling. This sound pretty serious.