文档章节

Java序列化与JSON序列化大比拼

NoahX
 NoahX
发布于 2013/03/10 16:35
字数 1406
阅读 19806
收藏 172

一、背景

有项目需要传输Map结构的数据,有人倾向用Java序列化来做,有人倾向用JSON的序列化来做。所以我们还是比比吧。

Java观点:Object2Object,使用时简单快速。

JSON观点:JSON格式与语言无关,扩展性强,速度也应该不慢。

大家可能对Java序列化都有一个错误的认识,认为Java序列化比JSON的序列化效率高并且序列化的数据小,其实实际上并不一定是这样,我这次就想通过实际测试来解开这个谜团

二、测试方式

测试同一个Map<String,Object>并序列化为byte[],并再将byte[]反序列化为Map<String,Object>的过程。Object中包括String,Integer,Long,Boolean,Float,Double常规类型的数据。

序列化:Map<String,Object> -> byte[]

反序列化:byte[] -> Map<String,Object>

测试各种大小不同的Map,并循环执行同一操作N次,来得到一个相对稳定的线性结果。

三、比较的对象

JAVA:

手写Java(1.6.0_32)与Common Lang3(3.1)的SerializationUtils。

JSON:

将采用Gson(2.2.2)与json-smart(2.0-RC2)两种不同的JSON解析器。json-smart号称是速度最快的JSON解析器。

、比较结果

Map大小(10-100)循环10万次

序列化时间比较(y为序列化时间ms)

反序列化时间比较(y为反序列化时间ms)


序列化时间汇总比较(y为序列化与反序列化总时间ms)

序列化后byte大小比较(由于同类线重合显示为2条线)

Map大小(100-1000)循环1万次

序列化时间比较(y为序列化时间ms)

反序列化时间比较(y为反序列化时间ms)

序列化时间汇总比较(y为序列化与反序列化总时间ms)

序列化后byte大小比较(由于同类线重合显示为2条线)

比较总结

Map在小于100时:
Java的反序列化时的性能要比Java序列化时性能差很多,1.5倍左右差距。
JSON序列化性能明显由于Java序列化性能,尤其是反序列化过程。并且序列化后的数据大小也是JSON格式的小。

Map在大于100小于1000时:
Java的反序列化时的性能并没有随Map的大小变化而变差。
JSON阵营中Gson在序列化过程中,比Java只快了那么一点点。在反序列化过程中Gson开始领先与Java,但在Map的大小过700多以后,Gson的反序列化性能
比Java要慢。但JSON阵营中的json-smart依然表现出色完全是两个级别。

并不是Java的序列化速度总是最快体积最小,Java需要考虑对象类型,属性类型与内部对象信息等一系列对数据本身并不相关的内容的处理。JSON以固定的格式,稳定简单的数据结构大大简化了序列化过程,虽然也要创建新的Java数据对象但并不会比Java反序列化的速度慢。

从测试结果上看JSON的json-smart更适合项目的需要。

五、测试代码源码

SerializationTest接口

package org.noahx.javavsjson;

import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 3/8/13
 * Time: 9:59 PM
 * To change this template use File | Settings | File Templates.
 */
public interface SerializationTest {

    public String getTestName();

    public Map<String, Object> testBytes2Map(byte[] bytes);

    public byte[] testMap2Bytes(Map<String, Object> map);
}


JavaSerializationTest

package org.noahx.javavsjson;

import java.io.*;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 3/8/13
 * Time: 10:05 PM
 * To change this template use File | Settings | File Templates.
 */
public class JavaSerializationTest implements SerializationTest {

    @Override
    public String getTestName() {
        return "Java";
    }

    @Override
    public Map<String, Object> testBytes2Map(byte[] bytes) {
        Map<String, Object> result = null;
        try {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);

            result = (Map<String, Object>) inputStream.readObject();
            inputStream.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    @Override
    public byte[] testMap2Bytes(Map<String, Object> map) {
        byte[] bytes = null;
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);

            outputStream.writeObject(map);
            outputStream.close();

            bytes = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }
}


CommonLang3SerializationTest

package org.noahx.javavsjson;

import org.apache.commons.lang3.SerializationUtils;

import java.io.Serializable;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 3/9/13
 * Time: 2:24 AM
 * To change this template use File | Settings | File Templates.
 */
public class CommonLang3SerializationTest implements SerializationTest {
    @Override
    public String getTestName() {
        return "Commons Lang3";
    }

    @Override
    public Map<String, Object> testBytes2Map(byte[] bytes) {
        return (Map<String, Object>) SerializationUtils.deserialize(bytes);
    }

    @Override
    public byte[] testMap2Bytes(Map<String, Object> map) {
        return SerializationUtils.serialize((Serializable) map);
    }
}


GsonSerializationTest

package org.noahx.javavsjson;

import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 3/8/13
 * Time: 10:02 PM
 * To change this template use File | Settings | File Templates.
 */
public class GsonSerializationTest implements SerializationTest {

    private Gson gson;

    public GsonSerializationTest() {
        gson = new Gson();
    }

    @Override
    public String getTestName() {
        return "Gson";
    }

    @Override
    public Map<String, Object> testBytes2Map(byte[] bytes) {
        Map<String, Object> result = null;
        try {
            result = gson.fromJson(new String(bytes, "UTF-8"), Map.class);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public byte[] testMap2Bytes(Map<String, Object> map) {
        String str = gson.toJson(map);
        byte[] bytes = null;
        try {
            bytes = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return bytes;
    }
}


JsonSmartSerializationTest

package org.noahx.javavsjson;

import net.minidev.json.JSONObject;
import net.minidev.json.JSONValue;
import net.minidev.json.parser.ParseException;

import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 3/9/13
 * Time: 1:30 AM
 * To change this template use File | Settings | File Templates.
 */
public class JsonSmartSerializationTest implements SerializationTest {
    @Override
    public String getTestName() {
        return "Json Smart";
    }

    @Override
    public Map<String, Object> testBytes2Map(byte[] bytes) {
        Map<String, Object> map = null;
        try {
            map = (Map<String, Object>) JSONValue.parseStrict((new String(bytes, "UTF-8")));
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return map;
    }

    @Override
    public byte[] testMap2Bytes(Map<String, Object> map) {
        String str = JSONObject.toJSONString(map);
        byte[] result = null;
        try {
            result = str.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }
}

源码下载:http://sdrv.ms/12ECmgG

P.S.

我也测试过Map<String,String>固定数据类型value只为String的情况,这时Java与JSON的性能的差距会减小,但JSON序列化性能与数据大小还是占优势,尤其是反序列化的速度JSON更出色。

Gson在数值反序列化后,因为Object无法确定类型,Map中的Long,Integer,Float统一转为了Double类型。
json-smart不一样,如果整数超过Integer的范围转Long,没有超过转Integer。浮点Float转为Double类型。


© 著作权归作者所有

NoahX
粉丝 136
博文 59
码字总数 48419
作品 0
海淀
程序员
私信 提问
加载中

评论(20)

chenq0922
chenq0922
http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/
小翔
小翔
接口之间最好还是用xml吧;json数据,太有结构层次了
NoahX
NoahX 博主

引用来自“snail9527”的评论

一直在用fastjson,不知道两者对比如何,有木有人对比过啊?

http://my.oschina.net/noahxiao/blog/112899
相同的测试方法加入上fastjson。
NoahX
NoahX 博主

引用来自“monolithic”的评论

引用来自“肖国颖”的评论

引用来自“咖啡杯”的评论

之前一直用fastjson,不知道和json-smart有没有关系

应该是两个框架
https://code.google.com/p/json-smart/
不过有时间我可以再实现一个测试一下

看到了json-smart网站有人贴的测试:
ser deser total
json/jackson-databind-strings 46% 84% 61%
json/fastjson-databind 45% 93% 64%
json/json-smart/manual/tree 100% 100% 100%
json/org.json/manual/tree 125% 208% 158%
json/json.simple/manual/tree 122% 228% 165%
json/jsonij-manual/tree 573% 175% 398%
json/argo-manual/tree-builders 1347% 533% 987%
json/json-lib-databind 559% 1762% 1050%
这个结果看起来fastjson和jackson都不错

http://my.oschina.net/noahxiao/blog/112899
相同的测试方法加入上fastjson。
南湖船老大
南湖船老大
这么看,json基本就是绝对优势了
snail_pang
snail_pang
一直在用fastjson,不知道两者对比如何,有木有人对比过啊?
NoahX
NoahX 博主

引用来自“alonedance”的评论

ubuntu 操作系统吗?

是,Ubuntu 12.10
Silencer
Silencer
ubuntu 操作系统吗?
x
xuningnb

引用来自“肖国颖”的评论

引用来自“咖啡杯”的评论

之前一直用fastjson,不知道和json-smart有没有关系

应该是两个框架
https://code.google.com/p/json-smart/
不过有时间我可以再实现一个测试一下

看到了json-smart网站有人贴的测试:
ser deser total
json/jackson-databind-strings 46% 84% 61%
json/fastjson-databind 45% 93% 64%
json/json-smart/manual/tree 100% 100% 100%
json/org.json/manual/tree 125% 208% 158%
json/json.simple/manual/tree 122% 228% 165%
json/jsonij-manual/tree 573% 175% 398%
json/argo-manual/tree-builders 1347% 533% 987%
json/json-lib-databind 559% 1762% 1050%
这个结果看起来fastjson和jackson都不错
Monkey
Monkey
吧序列化保存的文件打开看看就知道差别很大了。
有效选择七个关于 Java 的 JSON 开源类库

有效选择七个关于Java的JSON开源类库 April 4, 2014 By Constantin Marian Alin 翻译:无若 (英语原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-......

溪边九节
2014/04/19
12.9K
14
有效选择七个关于Java的JSON开源类库

April 4, 2014 By Constantin Marian Alin 翻译:无若 (英语原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-available-today.html) 简介 JSON是J......

无若
2014/04/19
6K
1
fastjson 发布 1.1.2 版本

fastjson是一个性能极致的json库,fastjson使得json这个文本协议具备二进制协议的性能。 fastjson 1.1.2是一个经过大量测试的版本,这个版本的发布目标就是提升稳定性,修正1.1.0以来因为优化...

wenshao
2011/08/02
1K
10
FastJson---高性能JSON开发包

Fastjson介绍 Fastjson是一个Java语言编写的JSON处理器,由阿里巴巴公司开发。 1、遵循http://json.org标准,为其官方网站收录的参考实现之一。 2、功能qiang打,支持JDK的各种类型,包括基本...

Zero零_度
2015/11/13
469
0
浅谈Java中JSON的序列化问题

在Java Web开发的过程中,时常会遇到与自己预期不一样的情况。有的时候静下心来自己去研究一番内在的原因还是很有趣的。这两天在写java web的时候,碰到了一个对象序列化的问题,问题大概是这...

小欣妹妹
2017/10/24
43
0

没有更多内容

加载失败,请刷新页面

加载更多

Netty整合Protobuffer

现在我们都知道,rpc的三要素:IO模型,线程模型,然后就是数据交互模型,即我们说的序列化和反序列化,现在我们来看一下压缩比率最大的二进制序列化方式——Protobuffer,而且该方式是可以跨...

算法之名
15分钟前
10
0
如何用C++实现栈

栈的定义 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压...

BWH_Steven
34分钟前
3
0
编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
46分钟前
6
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
今天
76
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部