This article uses JMH to test the performance of several common JSON parsing libraries in Java. Every time on the net to see what others say the performance of such and such library is how good, crushing other libraries. But seeing is believing. Only what you have tested yourself is believing.
JSON is a fairly common data transfer format in both Web and server development, and the performance of JSON parsing constructs is generally not a concern, except in high-performance systems.
At present, there are many kinds of Java open source JSON class libraries. Here, we take four common JSON libraries for performance testing and comparison, and select the most appropriate JSON library according to the test results.
The four JSON libraries are Gson, FastJson, Jackson, jSON-lib.
A simple introduction
Choosing an appropriate JSON library is a matter of consideration:
- String parsing into JSON performance
- String parsing into JavaBean performance
- JavaBean constructs JSON performance
- Collection constructs JSON performance
- Ease of use
First, a brief introduction to the identity background of the four class libraries
Gson
Project address: github.com/google/gson
Gson is the most fully functional Json parser. Gson was originally developed by Google for internal needs, but has been used by many companies or users since the first version was publicly released in May 2008. The application of Gson is mainly toJson and fromJson conversion functions, no dependency, no need to exception additional JAR, can run directly on JDK. Before using this object conversion, you need to create the object type and its members to successfully convert the JSON string into the corresponding object. As long as there are get and set methods in the class, Gson can fully implement jSON-to-bean or bean-to-JSON conversion of complex types, and is a magic tool for JSON parsing.
FastJson
Project address: github.com/alibaba/fas…
Fastjson is a high-performance JSON processor written in Java language, developed by Alibaba. No dependencies, no extra JAR exceptions, and the ability to run directly on the JDK. FastJson has some problems converting complex types of beans to Json. The type of reference may appear, leading to Json conversion errors and the need to specify the reference. FastJson uses an original algorithm that makes Parse faster than any OTHER JSON library.
Jackson
Project Address:
Github.com/FasterXML/j…
Jackson is the most widely used Java open source framework for serializing and deserializing JSON. Jackson is one of the most popular JSON parsers in Github, and the default JSON parser for Spring MVC is Jackson.
Jackson had many strengths:
- Jackson relies on fewer JARS and is easy to use.
- Jackson parses large JSON files faster than other Java JSON frameworks such as Gson.
- The Jackson runtime is low in memory footprint and performs well
- Jackson has a flexible API that can be easily extended and customized.
The latest version is 2.9.4, and Jackson’s core module consists of three parts:
- The jackson-core core package, which provides related apis based on “stream mode” parsing, includes JsonPaser and JsonGenerator. The Jackson internal implementation generates and parses JSON using JsonGenerator and JsonParser, the high-performance stream mode API.
- Annotations: The Jackson-Annotations package, which provides standard annotations;
- The Jackson-Databind data binding package provides apis based on object binding resolution (ObjectMapper) and tree model resolution (JsonNode); The API based on object binding parsing and the API based on tree model parsing rely on the API based on stream pattern parsing.
Why is Jackson’s introduction so long? Because it is also my favorite.
Json-lib
Project Address:
json-lib.sourceforge.net/index.html
Json-lib is one of the most widely used json parsing tools in the world. Json-lib relies on a lot of third-party packages. For complex types of conversion, json-lib also has disadvantages for converting json to beans, such as a list or map set of another class. Json-lib conversion from JSON to bean is problematic. Json-lib does not meet the needs of the Internet in terms of functionality and performance.
Writing performance tests
Next, start writing performance test code for these four libraries.
Adding Maven dependencies
First, of course, I add maven dependencies for all four libraries. To be fair, I use the latest versions of all of them:
<! -- Json libs--> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.82.</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.246.</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.94.</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.94.</version>
</dependency>
Copy the code
Four library utility classes
FastJsonUtil.java
public class FastJsonUtil {
public static String bean2Json(Object obj) {
return JSON.toJSONString(obj);
}
public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
returnJSON.parseObject(jsonStr, objClass); }}Copy the code
GsonUtil.java
public class GsonUtil {
private static Gson gson = new GsonBuilder().create();
public static String bean2Json(Object obj) {
return gson.toJson(obj);
}
public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
return gson.fromJson(jsonStr, objClass);
}
public static String jsonFormatter(String uglyJsonStr) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJsonStr);
returngson.toJson(je); }}Copy the code
JacksonUtil.java
public class JacksonUtil {
private static ObjectMapper mapper = new ObjectMapper();
public static String bean2Json(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
try {
return mapper.readValue(jsonStr, objClass);
} catch (IOException e) {
e.printStackTrace();
returnnull; }}}Copy the code
JsonLibUtil.java
public class JsonLibUtil {
public static String bean2Json(Object obj) {
JSONObject jsonObject = JSONObject.fromObject(obj);
return jsonObject.toString();
}
@SuppressWarnings("unchecked")
public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
return(T) JSONObject.toBean(JSONObject.fromObject(jsonStr), objClass); }}Copy the code
Prepare Model class
Here I write a simple Person class with attributes like Date, List, Map, and a custom class FullName to simulate the real world as much as possible.
public class Person {
private String name;
private FullName fullName;
private int age;
private Date birthday;
private List<String> hobbies;
private Map<String, String> clothes;
private List<Person> friends;
/ / getter/setter omitted
@Override
public String toString() {
StringBuilder str = new StringBuilder("Person [name=" + name + ", fullName=" + fullName + ", age="
+ age + ", birthday=" + birthday + ", hobbies=" + hobbies
+ ", clothes=" + clothes + "]");
if(friends ! = null) { str.append("Friends:");
for (Person f : friends) {
str.append("").append(f); }}returnstr.toString(); }}Copy the code
public class FullName {
private String firstName;
private String middleName;
private String lastName;
public FullName() {
}
public FullName(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
// omit the getter and setter
@Override
public String toString() {
return "[firstName=" + firstName + ", middleName="
+ middleName + ", lastName=" + lastName + "]"; }}Copy the code
JSON serialization performance benchmark
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonSerializeBenchmark {
/** * serialization times */
@Param({"1000"."10000"."100000"})
private int count;
private Person p;
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(JsonSerializeBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(0)
.build();
Collection<RunResult> results = new Runner(opt).run();
ResultExporter.exportResult("JSON Serialization Performance", results, "count"."Seconds");
}
@Benchmark
public void JsonLib() {
for (int i = 0; i < count; i++) {
JsonLibUtil.bean2Json(p);
}
}
@Benchmark
public void Gson() {
for (int i = 0; i < count; i++) {
GsonUtil.bean2Json(p);
}
}
@Benchmark
public void FastJson() {
for (int i = 0; i < count; i++) {
FastJsonUtil.bean2Json(p);
}
}
@Benchmark
public void Jackson() {
for (int i = 0; i < count; i++) {
JacksonUtil.bean2Json(p);
}
}
@Setup
public void prepare() {
List<Person> friends=new ArrayList<Person>();
friends.add(createAPerson("Xiao Ming",null));
friends.add(createAPerson("Tony",null));
friends.add(createAPerson("Xiao Er Chen",null));
p=createAPerson("Mr. Shao",friends);
}
@TearDown
public void shutdown() {
}
private Person createAPerson(String name,List<Person> friends) {
Person newPerson=new Person();
newPerson.setName(name);
newPerson.setFullName(new FullName("zjj_first"."zjj_middle"."zjj_last"));
newPerson.setAge(24);
List<String> hobbies=new ArrayList<String>();
hobbies.add("Basketball");
hobbies.add("Swimming");
hobbies.add("coding");
newPerson.setHobbies(hobbies);
Map<String,String> clothes=new HashMap<String, String>();
clothes.put("coat"."Nike");
clothes.put("trousers"."adidas");
clothes.put("shoes"."Anta");
newPerson.setClothes(clothes);
newPerson.setFriends(friends);
returnnewPerson; }}Copy the code
Just to illustrate, in the code above
ResultExporter.exportResult("JSON Serialization Performance", results, "count"."Seconds");
Copy the code
This is my own preparation of the performance test report data to fill the Echarts graph, and then export PNG image method, specific code I will not paste, refer to my Github source.
The result diagram after execution:
As can be seen from the above test results, when the number of serialization times is small, Gson performance is the best. When the number of serialization times increases to 100000, Gson details are weaker than Jackson and FastJson. In this case, FastJson performance is really good. Jackson has been doing well. And that JSON-lib is just for laughs. ^_^
JSON deserialization performance benchmark
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonDeserializeBenchmark {
/** * Deserialization times */
@Param({"1000"."10000"."100000"})
private int count;
private String jsonStr;
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(JsonDeserializeBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(0)
.build();
Collection<RunResult> results = new Runner(opt).run();
ResultExporter.exportResult("JSON deserialization performance", results, "count"."Seconds");
}
@Benchmark
public void JsonLib() {
for (int i = 0; i < count; i++) {
JsonLibUtil.json2Bean(jsonStr, Person.class);
}
}
@Benchmark
public void Gson() {
for (int i = 0; i < count; i++) {
GsonUtil.json2Bean(jsonStr, Person.class);
}
}
@Benchmark
public void FastJson() {
for (int i = 0; i < count; i++) {
FastJsonUtil.json2Bean(jsonStr, Person.class);
}
}
@Benchmark
public void Jackson() {
for (int i = 0; i < count; i++) {
JacksonUtil.json2Bean(jsonStr, Person.class);
}
}
@Setup
public void prepare() {
jsonStr="{"name":"Shao students","fullName": {"firstName":"zjj_first","middleName":"zjj_middle","lastName":"zjj_last"},"age: 24, ""birthday":null,"hobbies": ["basketball","swimming","coding"],"clothes": {"shoes":"anta","trousers":"adidas","coat":"Nike"},"friends": [{"name":"Xiao Ming","fullName": {"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age: 24, ""birthday":null,"hobbies": ["basketball","swimming","coding"],"clothes": {"shoes":"anta","trousers":"adidas","coat":"Nike"},"friends":null},{"name":"Tony","fullName": {"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age: 24, ""birthday":null,"hobbies": ["basketball","swimming","coding"],"clothes": {"shoes":"anta","trousers":"adidas","coat":"Nike"},"friends":null},{"name":"Chen Xiaoer","fullName": {"firstName":"xxx_first","middleName":"xxx_middle","lastName":"xxx_last"},"age: 24, ""birthday":null,"hobbies": ["basketball","swimming","coding"],"clothes": {"shoes":"anta","trousers":"adidas","coat":"Nike"},"friends":null}]}";
}
@TearDown
public void shutdown() {
}
}
Copy the code
The result diagram after execution:
As you can see from the above test results, when deserializing, Gson, Jackson, and FastJson, the performance is pretty good, and jSON-lib is still going to be funny.
Source:
www.xncoding.com/2018/01/09/…