jvm-serializers提供了一个很好的比较各种Java序列化的的测试套件。 它罗列了各种序列化框架, 可以自动生成测试报告。
我在AWS c3.xlarge机器上进行了测试,一下是测试报告与解析。
关键的测试数据的统计代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public double runWithTimeMeasurement(int timeMillis, TestCase tc, int iterations) throws Exception { long start = System.currentTimeMillis(); double sumTime = 0; int count = 0; System.err.println("test-time "+timeMillis+" iteration "+iterations); while ( System.currentTimeMillis()-start < timeMillis ) { double time = tc.run(transformer, serializer, value, iterations); sumTime += time; measurementVals[count] = time; count++; } double avg = sumTime / count; Arrays.sort(measurementVals,0,count); System.err.println("-----------------------------------------------------------------------------"); System.err.println(serializer.getName()); System.err.println("min:" + measurementVals[0]); System.err.println("1/4:"+measurementVals[count/4]); System.err.println("1/2:"+measurementVals[count/2]); System.err.println("3/4:"+measurementVals[count/4*3]); System.err.println("max:"+measurementVals[count-1]); System.err.println("average:"+ avg +" deviation:"+(avg-measurementVals[count/2])); System.err.println("-----------------------------------------------------------------------------"); return avg; } |
测试时序列化和反序列化会迭代多次,默认2000次。 测试会有一个限定时间,一轮测试完成后时间还有的话还会继续新的一轮的测试。 因此, 由于不同的框架花费的时间不同, 测试的轮数也不一样。
测试平台
OS:Linux (CentOS 6.4)
JVM:JDK 1.7.0_17
CPU: c3.xlarge
Cores (incl HT):4
免责声明
本测试主要关注无循环引用的数据结构, 但是如此众多的序列化框架还是各有不同:
- 有些支持循环引用检测
- 有些会输出全部的元数据,有些不会
- 有些支持跨平台,有些只支持特定的编程语言
- 有些是基于文本的,有些却基于二进制
- 有些支持向前向后兼容, 有些只支持向前或者向后,有些全部不支持
(查看ToolBehavior页面以了解一些框架的特性)
尽管别的测试数据可能会生成不同的测试结果(例如在每个字符串中增加非ascii字符), 此测试还是会提供一个各个序列化框架的性能的原始估计。
序列化框架Serializers(无共享引用)
- 无循环引用。 一个对象如果被引用两次则会序列化两次
- 没有手工优化
- schema预先已知
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
pre. create ser deser total size +dfl protostuff 112 663 917 1580 239 150 fst-flat-pre 81 908 984 1893 251 165 kryo-flat-pre 81 831 1083 1914 212 132 protobuf 149 1625 942 2567 239 149 msgpack-databind 81 1123 1821 2944 233 146 thrift-compact 139 1844 1101 2945 240 148 json/fastjson/databind 82 1710 1633 3343 486 262 thrift 139 2216 1253 3469 349 197 scala/sbinary 166 2122 1451 3573 255 147 smile/jackson+afterburner/databind 81 1757 1868 3625 352 252 smile/jackson/databind 81 2095 2250 4346 338 241 json/jackson+afterburner/databind 81 2006 2548 4554 485 261 json/protostuff-runtime 80 2008 2741 4748 469 243 json/jackson/databind 80 2173 2972 5145 485 261 json/jackson-jr/databind 81 2282 3435 5716 468 255 cbor/jackson/databind 81 4112 2659 6771 397 246 xml/jackson/databind 81 3558 7028 10585 683 286 json/gson/databind 81 7322 7063 14386 486 259 bson/jackson/databind 80 6974 8318 15291 506 286 xml/xstream+c 81 9050 28265 37315 487 244 xml/exi-manual 83 19634 18063 37697 337 327 json/javax-tree/glassfish 1558 16804 23814 40618 485 263 java-built-in 82 7154 37804 44958 889 514 scala/java-built-in 164 11195 62423 73617 1312 700 json/protobuf 142 11815 73133 84949 488 253 json/json-lib/databind 81 45857 165134 210991 485 263 |
全对象图序列化框架Full Object Graph Serializers
- 支持全部的object graph读写. Object graph可能包含循环引用.
- 无预先处理, 没有预先的类生成,注册. 所有都运行时产生, 比如使用反射.
- 注意通常不会跨编程语言。 然而JSON/XML格式由于其特殊性可以跨语言.
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed [light] in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
pre. create ser deser total size +dfl protostuff-graph 112 946 963 1909 239 150 protostuff-graph-runtime 82 1187 1208 2395 241 151 kryo-serializer 81 2091 1858 3949 286 188 fst 81 2075 2041 4116 316 203 jboss-marshalling-river-ct 81 4057 2810 6867 298 199 hessian 80 6683 7234 13917 501 313 jboss-serialization 83 9529 8508 18036 932 582 jboss-marshalling-river 81 5915 28347 34261 694 400 java-built-in-serializer 81 7273 36274 43547 889 514 stephenerialization 59 8396 37359 45756 1093 517 jboss-marshalling-serial 80 15148 39180 54328 856 498 yaml/jackson/databind 82 25969 41084 67053 505 260 json/flexjson/databind 81 25717 61700 87417 503 273 |
跨语言二进制序列化框架cross Lang Binary Serializers
- 无循环引用
- schema预先已知
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 |
pre. create ser deser total size +dfl protobuf/protostuff 113 695 927 1622 239 149 protobuf/protostuff-runtime 81 971 1105 2075 241 150 protobuf 149 1625 942 2567 239 149 msgpack-databind 81 1123 1821 2944 233 146 thrift-compact 139 1844 1101 2945 240 148 thrift 139 2216 1253 3469 349 197 cbor/jackson/databind 81 4112 2659 6771 397 246 hessian 80 6683 7234 13917 501 313 bson/jackson/databind 80 6974 8318 15291 506 286 |
XML/JSon序列化框架
- 基于文本
- Mixed regarding required preparation, object graph awareness (references).
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
pre. create ser deser total size +dfl json/fastjson/databind 82 1710 1633 3343 486 262 json/jackson+afterburner/databind 81 2006 2548 4554 485 261 json/protostuff-runtime 80 2008 2741 4748 469 243 json/jackson/databind 80 2173 2972 5145 485 261 json/jackson-jr/databind 81 2282 3435 5716 468 255 xml/jackson/databind 81 3558 7028 10585 683 286 json/gson/databind 81 7322 7063 14386 486 259 xml/xstream+c 81 9050 28265 37315 487 244 xml/exi-manual 83 19634 18063 37697 337 327 json/javax-tree/glassfish 1558 16804 23814 40618 485 263 yaml/jackson/databind 82 25969 41084 67053 505 260 json/protobuf 142 11815 73133 84949 488 253 json/flexjson/databind 81 25717 61700 87417 503 273 json/json-lib/databind 81 45857 165134 210991 485 263 |
手工优化的序列化框架Manually optimized Serializers
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
pre. create ser deser total size +dfl kryo-manual 81 670 792 1462 211 131 protostuff-manual 81 608 915 1523 239 150 wobly 48 1147 701 1848 251 151 kryo-opt 81 837 1059 1896 209 129 wobly-compact 48 1175 748 1923 225 139 java-manual 80 1341 848 2190 255 147 smile/jackson/manual 82 1270 1476 2746 341 244 msgpack-manual 80 1141 1668 2809 233 146 json/jackson/manual 83 1467 1949 3416 468 253 jboss-marshalling-river-ct-manual 82 2314 1586 3900 289 167 avro-generic 488 2485 1527 4012 221 133 avro-specific 118 2191 1916 4108 221 133 json/protostuff-manual 81 1757 2472 4229 449 233 cbor/jackson/manual 80 3659 1667 5326 386 238 xml/aalto-manual 82 2724 3902 6626 653 304 jboss-marshalling-river-manual 81 2967 5620 8587 483 240 json/gson/manual 81 4798 5826 10624 468 253 xml/woodstox-manual 81 4801 6355 11156 653 304 json/json-smart/manual-tree 82 7623 5110 12733 495 269 json/gson/manual-tree 82 7234 8202 15437 485 259 xml/fastinfo-manual 81 8406 7207 15613 377 284 xml/javolution/manual 80 6781 10766 17547 504 263 json/json.simple/manual 81 7394 10923 18317 495 269 json/org.json/manual-tree 81 8368 10959 19327 485 259 json/svenson/databind 81 5956 14026 19981 495 269 xml/xstream+c-aalto 81 5641 14743 20384 525 273 xml/xstream+c-fastinfo 81 10471 11640 22111 345 264 bson/mongodb/manual 81 4283 19559 23842 495 278 xml/xstream+c-woodstox 80 7326 18877 26203 525 273 json/javax-stream/glassfish 81 12791 21756 34547 468 253 json/jsonij/manual-jpath 83 38635 15094 53729 478 257 json/argo/manual-tree 81 85473 19416 104889 485 263 |
特性对性能的影响Cost of features
shows performance vs convenience of manually-selected libs.
- 循环引用, schema预知,手工优化cycle free, schema known at compile time, manual optimization: kryo-manual, msgpack-manual
- 循环引用, schema预知cycle free, schema known at compile time: protostuff, fst-flat-pre, kryo-flat-pre. (note: protostuff uses class generation while the other two just require a list of classes to be written)
- 循环引用, schema编译时未知 cycle free, schema UNKNOWN at compile time: fst-flat, kryo-flat, protostuff-runtime, msgpack-databind
- 全图读写,schema编译时未知 full object graph awareness, schema UNKNOWN at compile time: fst, kryo.
Ser Time+Deser Time (ns)
Ser
Time+Deser Time (ns)
Size, Compressed in bytes
Size,
Compressed in bytes
1 2 3 4 5 6 7 8 9 10 11 12 |
pre. create ser deser total size +dfl kryo-manual 81 670 792 1462 211 131 protostuff 112 663 917 1580 239 150 fst-flat-pre 81 908 984 1893 251 165 kryo-flat-pre 81 831 1083 1914 212 132 protostuff-runtime 82 839 1104 1943 241 151 kryo-flat 81 1037 1468 2505 268 177 fst-flat 81 1230 1469 2700 314 204 msgpack-manual 80 1141 1668 2809 233 146 msgpack-databind 81 1123 1821 2944 233 146 kryo-serializer 81 2091 1858 3949 286 188 fst 81 2075 2041 4116 316 203 |
全部的测试结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
pre. create ser deser total size +dfl kryo-manual 81 670 792 1462 211 131 protostuff-manual 81 608 915 1523 239 150 protostuff 112 663 917 1580 239 150 protobuf/protostuff 113 695 927 1622 239 149 wobly 48 1147 701 1848 251 151 fst-flat-pre 81 908 984 1893 251 165 kryo-opt 81 837 1059 1896 209 129 protostuff-graph 112 946 963 1909 239 150 kryo-flat-pre 81 831 1083 1914 212 132 wobly-compact 48 1175 748 1923 225 139 protostuff-runtime 82 839 1104 1943 241 151 protobuf/protostuff-runtime 81 971 1105 2075 241 150 java-manual 80 1341 848 2190 255 147 protostuff-graph-runtime 82 1187 1208 2395 241 151 kryo-flat 81 1037 1468 2505 268 177 protobuf 149 1625 942 2567 239 149 fst-flat 81 1230 1469 2700 314 204 smile/jackson/manual 82 1270 1476 2746 341 244 msgpack-manual 80 1141 1668 2809 233 146 msgpack-databind 81 1123 1821 2944 233 146 thrift-compact 139 1844 1101 2945 240 148 json/fastjson/databind 82 1710 1633 3343 486 262 json/jackson/manual 83 1467 1949 3416 468 253 thrift 139 2216 1253 3469 349 197 scala/sbinary 166 2122 1451 3573 255 147 smile/jackson+afterburner/databind 81 1757 1868 3625 352 252 jboss-marshalling-river-ct-manual 82 2314 1586 3900 289 167 kryo-serializer 81 2091 1858 3949 286 188 avro-generic 488 2485 1527 4012 221 133 avro-specific 118 2191 1916 4108 221 133 fst 81 2075 2041 4116 316 203 json/protostuff-manual 81 1757 2472 4229 449 233 smile/jackson/databind 81 2095 2250 4346 338 241 json/jackson+afterburner/databind 81 2006 2548 4554 485 261 json/protostuff-runtime 80 2008 2741 4748 469 243 json/jackson/databind 80 2173 2972 5145 485 261 cbor/jackson/manual 80 3659 1667 5326 386 238 json/jackson-jr/databind 81 2282 3435 5716 468 255 xml/aalto-manual 82 2724 3902 6626 653 304 cbor/jackson/databind 81 4112 2659 6771 397 246 jboss-marshalling-river-ct 81 4057 2810 6867 298 199 jboss-marshalling-river-manual 81 2967 5620 8587 483 240 xml/jackson/databind 81 3558 7028 10585 683 286 json/gson/manual 81 4798 5826 10624 468 253 xml/woodstox-manual 81 4801 6355 11156 653 304 json/json-smart/manual-tree 82 7623 5110 12733 495 269 hessian 80 6683 7234 13917 501 313 json/gson/databind 81 7322 7063 14386 486 259 bson/jackson/databind 80 6974 8318 15291 506 286 json/gson/manual-tree 82 7234 8202 15437 485 259 xml/fastinfo-manual 81 8406 7207 15613 377 284 xml/javolution/manual 80 6781 10766 17547 504 263 jboss-serialization 83 9529 8508 18036 932 582 json/json.simple/manual 81 7394 10923 18317 495 269 json/org.json/manual-tree 81 8368 10959 19327 485 259 json/svenson/databind 81 5956 14026 19981 495 269 xml/xstream+c-aalto 81 5641 14743 20384 525 273 xml/xstream+c-fastinfo 81 10471 11640 22111 345 264 bson/mongodb/manual 81 4283 19559 23842 495 278 xml/xstream+c-woodstox 80 7326 18877 26203 525 273 jboss-marshalling-river 81 5915 28347 34261 694 400 json/javax-stream/glassfish 81 12791 21756 34547 468 253 xml/xstream+c 81 9050 28265 37315 487 244 xml/exi-manual 83 19634 18063 37697 337 327 json/javax-tree/glassfish 1558 16804 23814 40618 485 263 java-built-in-serializer 81 7273 36274 43547 889 514 java-built-in 82 7154 37804 44958 889 514 stephenerialization 59 8396 37359 45756 1093 517 json/jsonij/manual-jpath 83 38635 15094 53729 478 257 jboss-marshalling-serial 80 15148 39180 54328 856 498 yaml/jackson/databind 82 25969 41084 67053 505 260 scala/java-built-in 164 11195 62423 73617 1312 700 json/protobuf 142 11815 73133 84949 488 253 json/flexjson/databind 81 25717 61700 87417 503 273 json/argo/manual-tree 81 85473 19416 104889 485 263 json/json-lib/databind 81 45857 165134 210991 485 263 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
pre. Effort Format Structure Misc kryo-manual MANUAL_OPT BINARY FLAT_TREE [] manually optimized protostuff-manual MANUAL_OPT BINARY FLAT_TREE [] manual protostuff CLASSES_KNOWN BINARY FLAT_TREE [] generated code protobuf/protostuff CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] protobuf + generated code wobly MANUAL_OPT BINARY FLAT_TREE [] fst-flat-pre CLASSES_KNOWN BINARY FLAT_TREE [] fst in unshared mode with preregistered classes kryo-opt MANUAL_OPT BINARY FLAT_TREE [] manually optimized protostuff-graph CLASSES_KNOWN BINARY FULL_GRAPH [] graph + generated code kryo-flat-pre CLASSES_KNOWN BINARY FLAT_TREE [] no shared refs, preregistered classes wobly-compact MANUAL_OPT BINARY FLAT_TREE [] protostuff-runtime ZERO_KNOWLEDGE BINARY FLAT_TREE [] reflection protobuf/protostuff-runtime ZERO_KNOWLEDGE BIN_CROSSLANG FLAT_TREE [] protobuf + reflection java-manual MANUAL_OPT BINARY FLAT_TREE [] protostuff-graph-runtime ZERO_KNOWLEDGE BINARY FULL_GRAPH [] graph + reflection kryo-flat ZERO_KNOWLEDGE BINARY FLAT_TREE [] default, no shared refs protobuf CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] fst-flat ZERO_KNOWLEDGE BINARY FLAT_TREE [] fst default, but unshared mode smile/jackson/manual MANUAL_OPT BINARY FLAT_TREE [] msgpack-manual MANUAL_OPT BIN_CROSSLANG FLAT_TREE [] msgpack-databind CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] thrift-compact CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] json/fastjson/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] json/jackson/manual MANUAL_OPT JSON FLAT_TREE [] thrift CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] scala/sbinary MISC MISC UNKNOWN [] null smile/jackson+afterburner/databind ZERO_KNOWLEDGE BINARY FLAT_TREE [] jboss-marshalling-river-ct-manual MANUAL_OPT BINARY FULL_GRAPH [] full graph preregistered classes, manual optimization kryo-serializer ZERO_KNOWLEDGE BINARY FULL_GRAPH [] default avro-generic MANUAL_OPT BIN_CROSSLANG FLAT_TREE [] avro-specific MANUAL_OPT BIN_CROSSLANG UNKNOWN [] fst ZERO_KNOWLEDGE BINARY FULL_GRAPH [] default: JDK serialization drop-in-replacement mode json/protostuff-manual MANUAL_OPT JSON FLAT_TREE [] json + manual smile/jackson/databind ZERO_KNOWLEDGE BINARY FLAT_TREE [] json/jackson+afterburner/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] uses bytecode generation to reduce overhead json/protostuff-runtime ZERO_KNOWLEDGE JSON FLAT_TREE [] json + reflection json/jackson/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] cbor/jackson/manual MANUAL_OPT BIN_CROSSLANG FLAT_TREE [] json/jackson-jr/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] xml/aalto-manual MANUAL_OPT XML UNKNOWN [] cbor/jackson/databind ZERO_KNOWLEDGE BIN_CROSSLANG FLAT_TREE [] jboss-marshalling-river-ct CLASSES_KNOWN BINARY FULL_GRAPH [] full graph with preregistered classes jboss-marshalling-river-manual MANUAL_OPT BINARY FULL_GRAPH [] full graph with manual optimizations xml/jackson/databind ZERO_KNOWLEDGE XML FLAT_TREE [] json/gson/manual MANUAL_OPT JSON FLAT_TREE [] xml/woodstox-manual MANUAL_OPT XML UNKNOWN [] json/json-smart/manual-tree MANUAL_OPT JSON FLAT_TREE [] hessian ZERO_KNOWLEDGE BIN_CROSSLANG FULL_GRAPH [] json/gson/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] bson/jackson/databind CLASSES_KNOWN BIN_CROSSLANG FLAT_TREE [] json/gson/manual-tree MANUAL_OPT JSON FLAT_TREE [] xml/fastinfo-manual MANUAL_OPT XML UNKNOWN [] xml/javolution/manual MANUAL_OPT XML FLAT_TREE [] jboss-serialization ZERO_KNOWLEDGE BINARY FULL_GRAPH [] json/json.simple/manual MANUAL_OPT JSON FLAT_TREE [] json/org.json/manual-tree MANUAL_OPT JSON FLAT_TREE [] json/svenson/databind MANUAL_OPT JSON FLAT_TREE [] xml/xstream+c-aalto MANUAL_OPT XML FLAT_TREE [] xml/xstream+c-fastinfo MANUAL_OPT XML FLAT_TREE [] bson/mongodb/manual MANUAL_OPT BIN_CROSSLANG FLAT_TREE [] xml/xstream+c-woodstox MANUAL_OPT XML FLAT_TREE [] jboss-marshalling-river ZERO_KNOWLEDGE BINARY FULL_GRAPH [] full graph zero knowledge json/javax-stream/glassfish MANUAL_OPT JSON FLAT_TREE [] xml/xstream+c ZERO_KNOWLEDGE XML FLAT_TREE [] xml/exi-manual ZERO_KNOWLEDGE XML UNKNOWN [] json/javax-tree/glassfish ZERO_KNOWLEDGE JSON FLAT_TREE [] java-built-in-serializer ZERO_KNOWLEDGE BINARY FULL_GRAPH [] java-built-in ZERO_KNOWLEDGE BINARY FLAT_TREE [] stephenerialization ZERO_KNOWLEDGE BINARY FULL_GRAPH [] null json/jsonij/manual-jpath MANUAL_OPT JSON FLAT_TREE [] jboss-marshalling-serial ZERO_KNOWLEDGE BINARY FULL_GRAPH [] yaml/jackson/databind ZERO_KNOWLEDGE JSON FULL_GRAPH [] scala/java-built-in MISC MISC UNKNOWN [] null json/protobuf CLASSES_KNOWN JSON FLAT_TREE [] json/flexjson/databind ZERO_KNOWLEDGE JSON FULL_GRAPH [] json/argo/manual-tree MANUAL_OPT JSON FLAT_TREE [] json/json-lib/databind ZERO_KNOWLEDGE JSON FLAT_TREE [] |