您的位置:首页 > Web前端 > JavaScript

FastJSON、Gson和Jackson性能对比和共同缺点,注意事项

2017-11-21 17:33 295 查看
先说重点:     JAVA是一种 强类型语言,这三种都是在后台每次返回的数据解析bean,不出错的情况下进行性能对比的,如果你之前的bean,有个字段为String类型, 而后台有次给你返回一个[] 空的数组等,这个时候,三种都会导致解析失败他们容错性在java强类型语言中表现不好.所以前提是都解析成功的情况下进行对比,如果想避免这种错误,就学习安卓的新语言Ktolin,他是弱类型语言,就不会产生这个问题,努力学习吧,少年!Java处理JSON数据有三个比较流行的类库FastJSON、Gson和Jackson。本文将测试这三个类库在JSON序列化和反序列化的方面表现,主要测试JSON序列化和反序列化的速度。为了防止由于内存导致测试结果出现偏差,测试中对JVM内存配置-Xmx4g -Xms4g。

JSON序列化(Object => JSON)

测试样本数量为100000个,为了保证每个类库在测试中都能处理同一个样本,先把样本Java对象保存在文件中。每个类库测试3次,每次循环测试10遍,去掉最快速度和最慢速度,对剩下的8遍求平均值作为最终的速,取3次测试中最好的平均速度作为最终的测试数据。
类库样本数量执行次数最长时间(毫秒)最短时间(毫秒)平均时间(毫秒)
FastJSON100000102291.221416.701454.93
Jackson100000101980.92841.91880.82
Gson100000102383.021469.081520.38
从测试数据可知,FastJSON和GsonJSON序列化的速度差不多,Jackson是最快的(用时Gson少大约600毫秒)。

JSON反序列化(JSON => Object)

测试样本数量为100000个,为了保证每个类库在测试中都能处理同一个样本,先把样本JSON对象保存在文件中。每个类库测试3次,每次循环测试10遍,去掉最快速度和最慢速度,对剩下的8遍求平均值作为最终的速,取3次测试中最好的平均速度作为最终的测试数据。
类库样本数量执行次数最长时间(毫秒)最短时间(毫秒)平均时间(毫秒)
FastJSON100000107942.316340.556526.41
Jackson100000107957.226623.856815.41
Gson100000108235.157006.067364.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;
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
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;
}

}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
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, 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) {
}
}
}
}
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: