Jackson和FastJson性能谁更快

来源:互联网 发布:iphone延时摄影软件 编辑:程序博客网 时间:2024/06/01 22:49

前言

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

1 0
原创粉丝点击