论坛首页 Java企业应用论坛

实际项目数据下的序列化性能对比:PHPRPC vs Hessian2 vs AMF3

浏览 14599 次
精华帖 (0) :: 良好帖 (13) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-03-17   最后修改:2009-03-17
看来这个优化还是很明显的,从40变成了10倍。哈哈~~

Timestamp 那个我也想改的,但是为了保持与其它语言的兼容实现,这个不能改,改了之后就不能跟其它语言和以前的版本互通了。

你能帮忙贴一个上面两个工具序列化一个对象之后的数据内容参考吗?

因为看不到数据,我实在找不到这个10倍的空间差距究竟是在哪儿引起的。
0 请登录后投票
   发表时间:2009-03-17  
andot 写道
看来这个优化还是很明显的,从40变成了10倍。哈哈~~

Timestamp 那个我也想改的,但是为了保持与其它语言的兼容实现,这个不能改,改了之后就不能跟其它语言和以前的版本互通了。

你能帮忙贴一个上面两个工具序列化一个对象之后的数据内容参考吗?

因为看不到数据,我实在找不到这个10倍的空间差距究竟是在哪儿引起的。

一条记录序列化测试结果:
引用
开始测试,序列化后二进制数据写进本地文件...

测试记录总数:1条

时间与空间:

Hessian:48毫秒,1417字节。
PHPRPC:21毫秒,3219字节。

结束测试


我测试代码中,Hessian目前的调用方式存在一个OutputStream最后buffer中数据无法写出的问题,故上面这个Hessian的测试结果是在buffer调整为64时测得的,时间没有参考性,但空间基本准确。

生成的数据见附件,我大概看了一下,可能是Hessian二进制的数据表达的空间优势。
0 请登录后投票
   发表时间:2009-03-18  
多谢多谢,我明天仔细研究研究。不过从这个结果上看,貌似没有10倍那么大的差距,真的好奇怪~
0 请登录后投票
   发表时间:2009-03-18   最后修改:2009-03-18
     ByteArrayOutputStream bos = new ByteArrayOutputStream();  
     Hessian2Output out = new Hessian2Output(bos);  
     long startT = System.currentTimeMillis();  
     for (int i = 0; i < vos.size(); i++) {  
         out.writeObject(vos.get(i));  
         os.write(bos.toByteArray());  
         bos.reset();  
     }  
     bos.close();


这部分应该改为:
     long startT = System.currentTimeMillis();
     for (int i = 0; i < vos.size(); i++) {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         Hessian2Output out = new Hessian2Output(bos);
         out.writeObject(vos.get(i));
         out.close();
         os.write(bos.toByteArray());
     }  


这样才可以保证 Hessian 的数据全部写入文件否则就会因为写入数据不全而造成 Hessian 写入文件的数据远远小于 PHPRPC 写入文件的数据,而实际上是数据丢失了。

修改之后再测一下,我想空间差距应该也是在 2 倍左右,而时间上应该也是 PHPRPC 稍快。
0 请登录后投票
   发表时间:2009-03-18  
没有找到Hessian2Output单个实例循环进行序列化动作的操作方法,其flush方法非一般理解的含义,会导致输出数据递增,暂时只能采取你的方法,故这次空间应该准确的,但多记录的序列化时间还是不具有说服力,测试结果:

phprpc优化后
引用
开始测试,序列化后二进制数据写进本地文件...

测试记录总数:15072条

时间与空间:

Hessian2 :25642毫秒, 22932252字节。
PHPRPC :9824毫秒, 47634761字节。

结束测试


phprpc优化前:
引用
开始测试,序列化后二进制数据写进本地文件...

测试记录总数:15072条

时间与空间:

Hessian2 :25545毫秒, 22932252字节。
PHPRPC :17246毫秒, 190715025字节。

结束测试


优化前的空间占用phprpc 8倍于Hessian,优化后为2倍,进步显著!

待有时间,基于Flex客户端和java服务器端,我测试一下大数据量复杂对象由服务器序列化、网络传输和客户端反序列化的全部时间,那才是真正有说服力的测试。
0 请登录后投票
   发表时间:2009-03-18   最后修改:2009-03-18
嗯,好的,期待全面的测试结果。有了测试结果就有明确的优化目标了。嘿嘿
0 请登录后投票
   发表时间:2009-03-18   最后修改:2009-03-18
加入AMF3的测试对比:

引用
测试记录总数:15072条

时间与空间:

Hessian2 :25534毫秒, 22932252字节。
PHPRPC   :9824毫秒,  47634761字节。
AMF3     :15724毫秒,  4447243字节。

结束测试


AMF3胜出,测试过程中发现AMF3序列化第一条记录时写入为1.4k,随后每条记录增加3k左右,故AMF3应是将所有写入的数据作为一个整体来进行cache,前提是只定义和循环使用一个AMF3Serializer实例。

Hessian2应该使用了和AMF3一样的cache策略,在修改Hessian2Output源码中Buffer为64后(只会丢弃最后buffer中数据),若只使用一个Hessian2Output实例,则第一条记录写入为1.4k,后续每条约3k多,最终空间大小和AMF3差不多。

这个结果中Hessian2的时间无参考价值,且未分析序列化的协议细节,故尚不能下结论。
0 请登录后投票
   发表时间:2009-03-18   最后修改:2009-03-18
fight_bird 写道
加入AMF3的测试对比:

引用
测试记录总数:15072条

时间与空间:

Hessian2 :25534毫秒, 22932252字节。
PHPRPC   :9824毫秒,  47634761字节。
AMF3     :15724毫秒,  4447243字节。

结束测试


AMF3胜出,测试过程中发现AMF3序列化第一条记录时写入为1.4k,随后每条记录增加3k左右,故AMF3应是将所有写入的数据作为一个整体来进行cache,前提是只定义和循环使用一个AMF3Serializer实例。

Hessian2应该使用了和AMF3一样的cache策略,在修改Hessian2Output源码中Buffer为64后(只会丢弃最后buffer中数据),若只使用一个Hessian2Output实例,则第一条记录写入为1.4k,后续每条约3k多,最终空间大小和AMF3差不多。

这个结果中Hessian2的时间无参考价值,且未分析序列化的协议细节,故尚不能下结论。


你上面的 AMF3 的数据总量应该是错的。因为你说第一条记录是1.4K,随后每条增加3K左右,可是 4447243/15072=295,也就是说一条记录平均只有 295 个字节,这显然与你前面说的“第一条记录时写入为1.4k,随后每条记录增加3k左右”有很大的矛盾,因此肯定还是跟第一次测试 Hessian 时一样把数据搞丢失了,所以 4447243 应该并不是实际的长度。

如果每次循环中创建一个 AMF3Serializer 的话,应该长度才是正确的。每次循环中创建一个 PHPSerializer 也是一样。你可以试一试。
0 请登录后投票
   发表时间:2009-03-18  
andot 写道
fight_bird 写道
加入AMF3的测试对比:

引用
测试记录总数:15072条

时间与空间:

Hessian2 :25534毫秒, 22932252字节。
PHPRPC   :9824毫秒,  47634761字节。
AMF3     :15724毫秒,  4447243字节。

结束测试


AMF3胜出,测试过程中发现AMF3序列化第一条记录时写入为1.4k,随后每条记录增加3k左右,故AMF3应是将所有写入的数据作为一个整体来进行cache,前提是只定义和循环使用一个AMF3Serializer实例。

Hessian2应该使用了和AMF3一样的cache策略,在修改Hessian2Output源码中Buffer为64后(只会丢弃最后buffer中数据),若只使用一个Hessian2Output实例,则第一条记录写入为1.4k,后续每条约3k多,最终空间大小和AMF3差不多。

这个结果中Hessian2的时间无参考价值,且未分析序列化的协议细节,故尚不能下结论。


你上面的 AMF3 的数据总量应该是错的。因为你说第一条记录是1.4K,随后每条增加3K左右,可是 4447243/15072=295,也就是说一条记录平均只有 295 个字节,这显然与你前面说的“第一条记录时写入为1.4k,随后每条记录增加3k左右”有很大的矛盾,因此肯定还是跟第一次测试 Hessian 时一样把数据搞丢失了,所以 4447243 应该并不是实际的长度。

如果每次循环中创建一个 AMF3Serializer 的话,应该长度才是正确的。每次循环中创建一个 PHPSerializer 也是一样。你可以试一试。

不好意思,我描述错误,每条增长是300字节左右,0.3k。
0 请登录后投票
   发表时间:2009-03-18   最后修改:2009-03-18
debug信息


Hessian2Output源码中SIZE字段调整为64
引用

开始测试,序列化后二进制数据写进本地文件...

测试记录总数:10条

时间与空间:

Hessian2 :
每记录增加数据量 = 1417 字节
每记录增加数据量 = 223 字节
每记录增加数据量 = 317 字节
每记录增加数据量 = 425 字节
每记录增加数据量 = 329 字节
每记录增加数据量 = 386 字节
每记录增加数据量 = 329 字节
每记录增加数据量 = 335 字节
每记录增加数据量 = 370 字节
每记录增加数据量 = 381 字节
51毫秒,4512字节。

PHPRPC :
每记录增加数据量 = 3219 字节
每记录增加数据量 = 3032 字节
每记录增加数据量 = 3215 字节
每记录增加数据量 = 3396 字节
每记录增加数据量 = 3254 字节
每记录增加数据量 = 3210 字节
每记录增加数据量 = 3230 字节
每记录增加数据量 = 3193 字节
每记录增加数据量 = 3236 字节
每记录增加数据量 = 3298 字节
84毫秒,32283字节。

AMF3 :
每记录增加数据量 = 1431 字节
每记录增加数据量 = 203 字节
每记录增加数据量 = 355 字节
每记录增加数据量 = 381 字节
每记录增加数据量 = 369 字节
每记录增加数据量 = 341 字节
每记录增加数据量 = 352 字节
每记录增加数据量 = 328 字节
每记录增加数据量 = 355 字节
每记录增加数据量 = 413 字节
28毫秒,4528字节。

结束测试



源码:
    private void serializeByAMF3(List<ImposedCorporationVO> vos) throws Exception {
        String filename = "serializeByAMF3-output";
        OutputStream os = new FileOutputStream(filename);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        AMF3Serializer serializer = new AMF3Serializer(bos);
        long startT = System.currentTimeMillis();
        System.out.println();
        for (int i = 0; i < vos.size(); i++) {
            serializer.writeObject(vos.get(i));
            byte[] temp = bos.toByteArray();
            System.out.println("每记录增加数据量 = " + temp.length + "字节");
            os.write(temp);
            bos.reset();
        }
        System.out.print((System.currentTimeMillis() - startT) + "毫秒,");
        os.flush();
        os.close();
        File outputFile = new File(filename);
        System.out.println(outputFile.length() + "字节。");
    }



    private void serializeByPhprpc(List<ImposedCorporationVO> vos) throws Exception {
        String filename = "serializeByPhprpc-output";
        OutputStream os = new FileOutputStream(filename);

        PHPSerializer formator1 = new PHPSerializer();
        long startT = System.currentTimeMillis();
        System.out.println();
        for (int i = 0; i < vos.size(); i++) {
            byte[] temp = formator1.serialize(vos.get(i));
            System.out.println("每记录增加数据量 = " + temp.length + "字节");
            os.write(temp);
        }
        System.out.print((System.currentTimeMillis() - startT) + "毫秒,");
        os.flush();
        os.close();
        File outputFile = new File(filename);
        System.out.println(outputFile.length() + "字节。");
    }


    private void serializeByHessian(List<ImposedCorporationVO> vos) throws Exception {
        String filename = "serializeByHessian-output";
        OutputStream os = new FileOutputStream(filename);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        Hessian2Output out = new Hessian2Output(bos);
        long startT = System.currentTimeMillis();
        System.out.println();
        for (int i = 0; i < vos.size(); i++) {
            out.writeObject(vos.get(i));
            byte[] temp = bos.toByteArray();
            System.out.println("每记录增加数据量 = " + temp.length + "字节");
            os.write(temp);
            bos.reset();
        }
        bos.close();
        System.out.print((System.currentTimeMillis() - startT) + "毫秒,");
        os.close();
        File outputFile = new File(filename);
        System.out.println(outputFile.length() + "字节。");
    }

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics