加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

FastJSON、Gson和Jackson性能对比

发布时间:2020-12-16 19:37:57 所属栏目:百科 来源:网络整理
导读:Java处理JSON数据有三个比较流行的类库FastJSON、Gson和Jackson。本文将测试这三个类库在JSON序列化和反序列化的方面表现,主要测试JSON序列化和反序列化的速度。为了防止由于内存导致测试结果出现偏差,测试中对JVM内存配置-Xmx4g -Xms4g。 JSON序列化(Obje

Java处理JSON数据有三个比较流行的类库FastJSON、Gson和Jackson。本文将测试这三个类库在JSON序列化和反序列化的方面表现,主要测试JSON序列化和反序列化的速度。为了防止由于内存导致测试结果出现偏差,测试中对JVM内存配置-Xmx4g -Xms4g。

JSON序列化(Object => JSON)

测试样本数量为100000个,为了保证每个类库在测试中都能处理同一个样本,先把样本Java对象保存在文件中。每个类库测试3次,每次循环测试10遍,去掉最快速度和最慢速度,对剩下的8遍求平均值作为最终的速,取3次测试中最好的平均速度作为最终的测试数据。

类库 样本数量 执行次数 最长时间(毫秒) 最短时间(毫秒) 平均时间(毫秒)
FastJSON 100000 10 2291.22 1416.70 1454.93
Jackson 100000 10 1980.92 841.91 880.82
Gson 100000 10 2383.02 1469.08 1520.38

从测试数据可知,FastJSON和GsonJSON序列化的速度差不多,Jackson是最快的(用时Gson少大约600毫秒)。

JSON反序列化(JSON => Object)

测试样本数量为100000个,为了保证每个类库在测试中都能处理同一个样本,先把样本JSON对象保存在文件中。每个类库测试3次,每次循环测试10遍,去掉最快速度和最慢速度,对剩下的8遍求平均值作为最终的速,取3次测试中最好的平均速度作为最终的测试数据。

类库 样本数量 执行次数 最长时间(毫秒) 最短时间(毫秒) 平均时间(毫秒)
FastJSON 100000 10 7942.31 6340.55 6526.41
Jackson 100000 10 7957.22 6623.85 6815.41
Gson 100000 10 8235.15 7006.06 7364.75

从测试数据可知,三个类库在反序列化上性能比较接近,Gson稍微差一些。

总结

把Java对象JSON序列化,Jackson速度最快,在测试中比Gson快接近50%,FastJSON和Gson速度接近。
把JSON反序列化成Java对象,FastJSON、Jackson速度接近,Gson速度稍慢,不过差距很小。

样本对象

样本对象包括Boolean、Int、Long、Double、Date、String、List和Map字段,其中List长度和Map的Key数量可以根据需要改变。

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/** * 该类提供生成样本的元数据 * @author accountwcx@qq.com * */
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;

/** * 样本对象 * @author accountwcx@qq.com * */
public class SampleEntity 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 SampleEntity() {
        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 SampleEntity(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;
    }

}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;

import com.alibaba.fastjson.JSON;

/** * 创建样本 * @author accountwcx@qq.com * */
public class SampleBuilder {

    public static void main(String[] args) {
        int sampleSize = 100000;
        String jsonDataPath = "d:samples_json.dat";
        String objectDataPath = "d:samples_object.dat";

        buildJsonSamples(sampleSize,10,jsonDataPath);
        buildObjectSamples(sampleSize,objectDataPath);
    }

    public static List<String> loadJSONSamples(String filePath) {
        List<String> list = new LinkedList<String>();

        File file = new File(filePath);
        if (!file.exists()) {
            return list;
        }

        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(file));
            String line = br.readLine();            
            while(line != null){
                list.add(line);
                line = br.readLine();
            }           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
        }

        return list;
    }

    @SuppressWarnings("unchecked")
    public static List<SampleEntity> loadSamples(String filePath) {
        List<SampleEntity> list = new LinkedList<SampleEntity>();

        File file = new File(filePath);
        if (!file.exists()) {
            return list;
        }

        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(file));
            list = (List<SampleEntity>) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != ois) {
                try {
                    ois.close();
                } catch (IOException e) {
                }
            }
        }

        return list;
    }

    /** * 创建样本 * * @param sampleSize 样本数量 * @param listSize 样本List长度 * @param mapKeyNum 样本Map的Key数量 * @return 样本List */
    public static List<SampleEntity> buildSamples(int sampleSize,int listSize,int mapKeyNum) {
        List<SampleEntity> list = new LinkedList<SampleEntity>();
        for (int i = 0; i < sampleSize; i++) {
            list.add(new SampleEntity(listSize,mapKeyNum));
        }

        return list;
    }

    /** * 用默认参数创建样本,其中listSize默认为10,mapKeyNum默认为10。 * * @param sampleSize * @return 样本List */
    public static List<SampleEntity> buildSamples(int sampleSize) {
        List<SampleEntity> list = new LinkedList<SampleEntity>();
        for (int i = 0; i < sampleSize; i++) {
            list.add(new SampleEntity());
        }

        return list;
    }

    /** * 创建样本,并把样本JSON序列化,保存到文件中。 * * @param sampleSize 样本数量 * @param listSize 样本List长度 * @param mapKeyNum 样本Map中Key的数量 * @param filePath 样本输出的文件路径 */
    public static void buildJsonSamples(int sampleSize,int mapKeyNum,String filePath) {
        File file = new File(filePath);
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        List<SampleEntity> list = buildSamples(sampleSize,listSize,mapKeyNum);

        StringBuilder sb = new StringBuilder();
        for (SampleEntity item : list) {
            sb.append(JSON.toJSONString(item));
            sb.append("n");
        }

        BufferedWriter bw = null;
        try {
            file.createNewFile();

            bw = new BufferedWriter(new FileWriter(file));
            bw.write(sb.toString());
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static void buildJsonSamples(int sampleSize,String filePath) {
        File file = new File(filePath);
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        List<SampleEntity> list = buildSamples(sampleSize);

        StringBuilder sb = new StringBuilder();
        for (SampleEntity item : list) {
            sb.append(JSON.toJSONString(item));
            sb.append("n");
        }

        BufferedWriter bw = null;
        try {
            file.createNewFile();

            bw = new BufferedWriter(new FileWriter(file));
            bw.write(sb.toString());
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static void buildObjectSamples(int sampleSize,String filePath) {
        List<SampleEntity> list = buildSamples(sampleSize);

        File file = new File(filePath);
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        ObjectOutputStream oos = null;
        try {
            file.createNewFile();

            oos = new ObjectOutputStream(new FileOutputStream(file));
            oos.writeObject(list);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != oos) {
                try {
                    oos.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /** * 生成样本对象,并保存到指定文件 * * @param sampleSize 样本大小 * @param listSize 样本中List字段长度 * @param mapKeyNum 样本中Map对象Key数量 * @param filePath 样本输出的路径 */
    public static void buildObjectSamples(int sampleSize,String filePath) {
        List<SampleEntity> list = buildSamples(sampleSize,mapKeyNum);

        File file = new File(filePath);
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        ObjectOutputStream oos = null;
        try {
            file.createNewFile();

            oos = new ObjectOutputStream(new FileOutputStream(file));
            oos.writeObject(list);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != oos) {
                try {
                    oos.close();
                } catch (IOException e) {
                }
            }
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读