我们将去了解java中二进制序列化的性能,下面的类将参与比较:
以我的经验,所有这些序列化方法的性能既依赖于数据节点的数量,又依赖于缓冲区或流的类型。因此我写了两组测试。第一个测试工作在只有单一字段 byte[500] 的对象,然而第二个测试使用另一个具其他单一字段-long[500] 的对象。在 ByteBuffer 和 Unsafe 测试中,我们会测试大量的操作,在每次单独的调用中都会序化每个数组元素。
首先,下面是第二联盟 (sencond league) 的测试结果:流。出于比较目的,我们将记录下使用小端堆(heap little-endian)的 ByteBuffer 迭代次数相同的结果。请注意,我们在第二测试联盟中使用的迭代次数比较小。
两次测试中,每个单元格显示的是 Java6/Java7 运行一次需要的秒数。
| Structure: | DataOutputStream (ByteArrayOutputStream) | DataInputStream (ByteArrayInputStream) | DataInputStream (BAInputStream – not synchronized) | ByteBuffer |
|---|---|---|---|---|
| Type | Heap | |||
| Endian | Little | |||
| Write 1M byte buffers (500 bytes) | 16.178/15.74 | - | - | 0.362/0.379 |
| Read 1M byte buffers (500 bytes) | - | 16.106/16.424 | 2.432/2.361 | 0.471/0.508 |
| Write 1M long buffers (500 longs) | 11.735/11.632 | - | - | 3.771/3.691 |
| Read 1M long buffers (500 longs) | - | 11.747/11.622 | 9.966/9.532 | 6.062/4.069 |
需要注意的是:在ByteArray流上同步对小数据类型的影响要大于大数据类型。字符操作中,同步和不同步的版本性能相差8倍,这确实是个问题!
在第一阵营中,我们将比较各种通过 sun.misc.Unsafe 进行内存访问的 ByteBuffers。不幸的是,Unsafe 类只工作在本地字节顺序下(大端或小端)。通过使用 Short/Integer/Long.reverseBytes 方法(覆盖2/4/8字节数据类型)可以解决该问题,但没有临时缓冲区的话,大量的非本地字节顺序的操作是不可能的,即使有临时缓冲区也没多大意义-这意味着2数据拷贝而不是一个。
| Structure: | ByteBuffer | ByteBuffer | ByteBuffer | ByteBuffer | Unsafe | |
|---|---|---|---|---|---|---|
| Type | Heap | Heap | Direct | Direct | ||
| Endian | Little | Big | Little | Big | Little (native) | |
| Write 80M byte buffers (as bytes) | 26.21/26.26 | 27.457/27.365 | 101.967/43.338 | 102.912/43.396 | 31.578/31.846 | |
| Write 80M byte buffers (as 1 byte[]) | 2.966/2.888 | 3.489/3.321 | 4.036/4.016 | 4.27/4.038 | 2.456/2.035 | |
| Read 80M byte buffers (as bytes) | 56.163/36.089 | 56.322/36.084 | 40.1/41.411 | 40.519/41.195 | 36.68/41.711 | |
| Read 80M byte buffers (as 1 byte[]) | 6.909/6.842 | 6.926/7.036 | 6.795/6.808 | 7.377/7.176 | 6.307/6.317 | |
| Write 10M long buffers (as longs) | 36.179/37.316 | 51.063/51.221 | 14.702/7.366 | 64.305/10.127 | 7.301/6.699 | |
| Write 10M long buffers (as 1 long[]) | 32.301/29.651 | 53.477/54.115 | 2.014/1.912 | 27.265/28.319 | 1.703/1.701 | |
| Read 10M long buffers (as longs) | 59.625/39.923 | 53.978/52.097 | 26.715/10.941 | 67.355/15.932 | 8.492/10.026 | |
| Read 10M long buffers (as 1 long[]) | 47.19/36.373 | 60.107/35.186 | 6.668/6.754 | 32.925/35.071 | 6.075/6.143 |
我们发现了什么?

