java序列化和json序列化效率对比

一、背景

有项目需要传输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接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

?
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
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

?
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
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

?
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
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

?
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
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类型。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java中的JSON序列化和反序列化是将Java对象转换为JSON格式的字符串,或将JSON格式的字符串转换为Java对象的过程。 在Java中,可以使用各种库来进行JSON序列化和反序列化,比较常用的有以下几种: 1. Jackson:Jackson是一个功能强大且广泛使用的JSON处理库,它提供了一系列的API来实现JSONJava对象之间的转换。通过Jackson,可以将Java对象转换为JSON字符串,或将JSON字符串转换为Java对象。 2. Gson:Gson是Google提供的一个简单易用的JSON处理库,它可以将Java对象转换为JSON字符串,或将JSON字符串转换为Java对象。Gson提供了一些简单的API来实现序列化和反序列化操作。 3. Fastjson:Fastjson是阿里巴巴开源的一个高性能的JSON处理库,它支持将Java对象转换为JSON字符串,或将JSON字符串转换为Java对象。Fastjson提供了一些灵活的API来实现序列化和反序列化操作。 这些库都提供了类似的API,可以根据具体需求选择适合的库进行使用。一般来说,使用这些库进行JSON序列化和反序列化的步骤如下: 1. 创建一个Java对象,并设置相应的属性值。 2. 使用JSON处理库的API将Java对象转换为JSON字符串,或将JSON字符串转换为Java对象。 下面是一个使用Jackson库进行JSON序列化和反序列化的示例代码: ```java import com.fasterxml.jackson.databind.ObjectMapper; public class JsonSerializationExample { public static void main(String[] args) throws Exception { // 创建一个Java对象 Person person = new Person("John", 25); // 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); // 将Java对象转换为JSON字符串 String jsonString = objectMapper.writeValueAsString(person); System.out.println("JSON String: " + jsonString); // 将JSON字符串转换为Java对象 Person deserializedPerson = objectMapper.readValue(jsonString, Person.class); System.out.println("Deserialized Person: " + deserializedPerson); } } class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } // 省略getter和setter方法 @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } ``` 这个示例中,首先创建了一个Person对象,然后使用ObjectMapper将Person对象转换为JSON字符串,并输出结果。接着,将JSON字符串转换为Java对象,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值