Jackson和FastJson性能谁更快
2016-07-24 01:09
369 查看
前言
jackson和fastjson大概是我们使用得最多的两个json序列化包和反序列化包。网上的性能对比很多,大多数的结果对fastjson都不利,甚至有的结论是比Gson还要慢,但是我觉得fastjson是阿里系的,应该性能不会差,于是作了一系列对比。我们这里使用的是最新的两个包jackjson为2.8版本,而fastjson为1.2.14版本对比使用对象
在对比中使用的对象基本包含了所有的数据类型和集合,并且是随机生成。这里我直接借鉴了别人测试的时候使用的对象,因为的确比较好,我便没有修改,代码如下:/** * Created by lz on 2016/7/23. */ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; /** * 该类提供生成样本的元数据 * */ public class DataBuilder { private static final String[] chars = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; private static final int charNum = 62; // 样本String最大长度 private static final int maxStrLength = 100; // 样本String默认长度 private static final int defaultStrLength = 50; // 样本List最大长度 private static final int maxListSize = 100; // 样本List默认长度 private static final int defaultListSize = 10; // 样本Map最大Key数量 private static final int maxMapSize = 100; // 样本Map默认Key数量 private static final int defaultMapSize = 10; // 样本Map中Value的数据类型 private static final String[] types = new String[] { "boolean", "int", "long", "double", "date", "string"}; private static final int typeNum = 6; private static final Random random = new Random(); /** * 生成随机长度的字符串 * @return 字符串 */ public static String randomString(){ return randomString(random.nextInt(maxStrLength)); } /** * 生成指定长度的字符串 * @param len 字符串长度 * @return */ public static String randomString(int len) { if (len < 1 || len > maxStrLength) { // 如果字符串长度超出范围,使用默认长度 len = defaultStrLength; } StringBuilder sb = new StringBuilder(len); for (int i = 0; i < len; i++) { sb.append(chars[random.nextInt(charNum)]); } return sb.toString(); } /** * 生成List样本,List中元素的数量随机 * @return */ public static List<String> randomStringList() { return randomStringList(random.nextInt(maxListSize)); } /** * 生成List样本 * @param size List中元素的数量 * @return */ public static List<String> randomStringList(int size) { if (size < 1 || size > maxListSize) { size = defaultListSize; } List<String> list = new ArrayList<String>(); for (int i = 0; i < size; i++) { list.add(randomString(random.nextInt(maxStrLength))); } return list; } /** * 生成随机Map样本,样本中key的数量随机 * @return */ public static Map<String, Object> randomMap() { return randomMap(random.nextInt(maxMapSize)); } /** * 生成随机Map样本 * @param size 样本中key的数量 * @return */ public static Map<String, Object> randomMap(int size) { if (size < 1 || size > maxMapSize) { size = defaultMapSize; } Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < size; i++) { String type = types[random.nextInt(typeNum)]; if ("boolean".equals(type)) { map.put("key" + i, random.nextBoolean()); } else if ("int".equals(type)) { map.put("key" + i, random.nextInt()); } else if ("long".equals(type)) { map.put("key" + i, random.nextLong()); } else if ("double".equals(type)) { map.put("key" + i, random.nextDouble()); } else if ("date".equals(type)) { map.put("key" + i, new Date()); } else if ("string".equals(type)) { map.put("key" + i, randomString(random.nextInt(maxStrLength))); } } return map; } }
以及
import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Random; /** * 样本对象 * */ public class JsonObject implements Serializable { private static final long serialVersionUID = -1520171788566678009L; private Boolean fieldBoolean; private Integer fieldInt; private Long fieldLong; private Double fieldDouble; private Date fieldDate; private String fieldStr; private List<String> fieldList; private Map<String, Object> fieldMap; /** * 随机样本 */ public JsonObject() { Random random = new Random(); fieldBoolean = random.nextBoolean(); fieldInt = random.nextInt(); fieldLong = random.nextLong(); fieldDouble = random.nextDouble(); fieldDate = new Date(); fieldStr = DataBuilder.randomString(); fieldList = DataBuilder.randomStringList(); fieldMap = DataBuilder.randomMap(); } /** * 指定List元素数量和Map元素数量的样本 * @param listSize List元素数量 * @param mapKeyNum Map元素数量 */ public JsonObject(int listSize, int mapKeyNum) { Random random = new Random(); fieldBoolean = random.nextBoolean(); fieldInt = random.nextInt(); fieldLong = random.nextLong(); fieldDouble = random.nextDouble(); fieldDate = new Date(); fieldStr = DataBuilder.randomString(); fieldList = DataBuilder.randomStringList(listSize); fieldMap = DataBuilder.randomMap(mapKeyNum); } public Boolean getFieldBoolean() { return fieldBoolean; } public void setFieldBoolean(Boolean fieldBoolean) { this.fieldBoolean = fieldBoolean; } public Integer getFieldInt() { return fieldInt; } public void setFieldInt(Integer fieldInt) { this.fieldInt = fieldInt; } public Long getFieldLong() { return fieldLong; } public void setFieldLong(Long fieldLong) { this.fieldLong = fieldLong; } public Double getFieldDouble() { return fieldDouble; } public void setFieldDouble(Double fieldDouble) { this.fieldDouble = fieldDouble; } public Date getFieldDate() { return fieldDate; } public void setFieldDate(Date fieldDate) { this.fieldDate = fieldDate; } public String getFieldStr() { return fieldStr; } public void setFieldStr(String fieldStr) { this.fieldStr = fieldStr; } public List<String> getFieldList() { return fieldList; } public void setFieldList(List<String> fieldList) { this.fieldList = fieldList; } public Map<String, Object> getFieldMap() { return fieldMap; } public void setFieldMap(Map<String, Object> fieldMap) { this.fieldMap = fieldMap; } }
测试方法
我们的测试策略如下:输入需要测试的个数,例如输入10000,然后会对此进行测试10次,按照国际惯例去掉时间最小的,和一个时间最大的,剩下的8次再来求平均值,得到的就是我们所要求得平均速度,这里我们需要测试10个数据 1000个数据 10万个数据。代码如下:
import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 测试方法 * 输入需要测试的个数 * 例如输入10000 * 然后会对此进行测试10次,去掉时间最小的,和一个时间最大的,剩下的8次再来求平均值 * 得到的就是我们所要求得平均速度 * 这里我们需要测试10个数据 1000个数据 10万个数据 * Created by lz on 2016/7/24. */ public class TestMain { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** * 传入数据的个数 * @param nums * @return */ public static List<Double> complete(int nums) throws Exception { Double[] jacksonTimes = new Double[10]; Double[] fastjsonTimes = new Double[10]; Double[] jacksonTimes1 = new Double[10]; Double[] fastjsonTimes1 = new Double[10]; List<Double> time = new ArrayList<Double>(); for (int i = 0; i < 10 ; i++) { List<Double> list = getTime(nums); jacksonTimes[i]=list.get(0); fastjsonTimes[i]=list.get(1); jacksonTimes1[i]=list.get(2); fastjsonTimes1[i]=list.get(3); } Arrays.sort(jacksonTimes); Arrays.sort(fastjsonTimes); Arrays.sort(jacksonTimes1); Arrays.sort(fastjsonTimes1); Double sum = 0.00; for (int i = 1; i < 9; i++) { sum += jacksonTimes[i]; } time.add(sum/8); sum=0.00; for (int i = 1; i < 9; i++) { sum += fastjsonTimes[i]; } time.add(sum/8); sum=0.00; for (int i = 1; i < 9; i++) { sum += jacksonTimes1[i]; } time.add(sum/8); sum=0.00; for (int i = 1; i < 9; i++) { sum += fastjsonTimes1[i]; } time.add(sum/8); return time; } /** * 传入数据的个数 * @param nums * @return list.get(0)是jackson本次的时间 list.get(1)是fastjson本次的时间 */ public static List<Double> getTime(int nums) throws Exception { Double jacksonTime1 = 0.00; Double fastjsonTime1 = 0.00; Double jacksonTime2 = 0.00; Double fastjsonTime2 = 0.00; for (int i = 0; i < nums; i++) { //这里我们生成jsonObject JsonObject jsonObject = new JsonObject(); long start,end; String str = null; start = System.currentTimeMillis(); str = OBJECT_MAPPER.writeValueAsString(jsonObject); end = System.currentTimeMillis(); jacksonTime1 += Double.valueOf(end-start); start = System.currentTimeMillis(); str = JSON.toJSONString(jsonObject); end = System.currentTimeMillis(); fastjsonTime1 += Double.valueOf(end-start); start = System.currentTimeMillis(); OBJECT_MAPPER.readValue(str, JsonObject.class); end = System.currentTimeMillis(); jacksonTime2 += Double.valueOf(end-start); start = System.currentTimeMillis(); JSON.parseObject(str,JsonObject.class); end = System.currentTimeMillis(); fastjsonTime2 += Double.valueOf(end-start); } List<Double> list = new ArrayList<Double>(); list.add(jacksonTime1); list.add(fastjsonTime1); list.add(jacksonTime2); list.add(fastjsonTime2); return list; } public static void main(String[] args) throws Exception { //输入测试个数,得到时间 List<Double> list10 = complete(10); List<Double> list1000 = complete(1000); List<Double> list100000 = complete(100000); System.out.println("------------------------序列化时间比较----------------------------"); System.out.println("测试数据为10的时候:jackson序列化时间:"+list10.get(0)+"ms | fastjson序列化时间"+list10.get(1)+"ms"); System.out.println("测试数据为1000的时候:jackson序列化时间:"+list1000.get(0)+"ms | fastjson序列化时间"+list1000.get(1)+"ms"); System.out.println("测试数据为100000的时候:jackson序列化时间:"+list100000.get(0)+"ms | fastjson序列化时间"+list100000.get(1)+"ms"); System.out.println("------------------------反序列化时间比较----------------------------"); System.out.println("测试数据为10的时候:jackson反序列化时间:"+list10.get(2)+"ms | fastjson反序列化时间"+list10.get(3)+"ms"); System.out.println("测试数据为1000的时候:jackson反序列化时间:"+list1000.get(2)+"ms | fastjson反序列化时间"+list1000.get(3)+"ms"); System.out.println("测试数据为100000的时候:jackson反序列化时间:"+list100000.get(2)+"ms | fastjson反序列化时间"+list100000.get(3)+"ms"); } }
最后的结果:
————————序列化时间比较—————————-
测试数据为10的时候:jackson序列化时间:5.0ms | fastjson序列化时间4.75ms
测试数据为1000的时候:jackson序列化时间:61.375ms | fastjson序列化时间45.875ms
测试数据为100000的时候:jackson序列化时间:2448.875ms | fastjson序列化时间2421.375ms
————————反序列化时间比较—————————-
测试数据为10的时候:jackson反序列化时间:13.0ms | fastjson反序列化时间9.25ms
测试数据为1000的时候:jackson反序列化时间:148.375ms | fastjson反序列化时间133.625ms
测试数据为100000的时候:jackson反序列化时间:9488.625ms | fastjson反序列化时间9356.75ms
结论
有时候,别人做的东西还真的不能信,必须要自己亲身体验测试过才知道速度的快慢,fastjson并不是像很多人说的速度要慢很多,基本序列化时间和反序列化时间都是55开的甚至fastjson可能要略胜与jackson。github地址:https://github.com/lzggsimida123/json1
相关文章推荐
- 使用 Python 处理 JSON 格式的数据
- XML 与 JSON 优劣对比
- VBA将excel数据表生成JSON文件
- 选定虚拟主机 性能凸显优势
- 修改一行代码提升 Postgres 性能 100 倍
- newtonsoft.json解析天气数据出错解决方法
- redis的hGetAll函数的性能问题(记Redis那坑人的HGETALL)
- 推荐Sql server一些常见性能问题的解决方法
- SQL Server误区30日谈 第9天 数据库文件收缩不会影响性能
- 和表值函数连接引发的性能问题分析
- SQLServer 2000 升级到 SQLServer 2008 性能之需要注意的地方之一
- 数据库性能优化三:程序操作优化提升性能
- vbs 解析json jsonp的方法
- VBS中的字符串连接的性能问题
- Ruby和Ruby on Rails中解析JSON格式数据的实例教程
- Extjs4如何处理后台json数据中日期和时间
- C#实现将类的内容写成JSON格式字符串的方法
- JQuery ajax返回JSON时的处理方式 (三种方式)
- jquery JSON的解析方式示例介绍
- c#版json数据解析示例分享