FastJSON、Gson和Jackson性能對比

原文地址:

http://blog.csdn.net/accountwcx/article/details/50252657

http://blog.csdn.net/anmoyyh/article/details/70598557

http://blog.csdn.net/zhanggang740/article/details/52278373

http://blog.csdn.net/xiaoke815/article/details/52920405

http://blog.csdn.net/li563868273/article/details/52010695

http://www.cnblogs.com/lixiaoran/p/5607870.html

https://segmentfault.com/q/1010000005914639?_ea=956077


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 [email protected]
 *
 */
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;
    }
}
  • 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
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 樣本對象
 * @author [email protected]
 *
 */
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;
    }

}
  • 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
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
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 [email protected]
 *
 */
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, 10, jsonDataPath);
        buildObjectSamples(sampleSize, 10, 10, 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 listSize, 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, int listSize, int mapKeyNum, String filePath) {
        List<SampleEntity> list = buildSamples(sampleSize, listSize, 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) {
                }
            }
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章