Skip to content

Instantly share code, notes, and snippets.

@varren
Last active September 20, 2017 02:51
Show Gist options
  • Save varren/3b7468a1d7abadad4958fe6bd7d42d44 to your computer and use it in GitHub Desktop.
Save varren/3b7468a1d7abadad4958fe6bd7d42d44 to your computer and use it in GitHub Desktop.
Jackson performance Tests
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.*;
public class Main {
public static String json = "{\"d\": {\"results\": [{\"name\":\"one\"},{\"name\":\"two\"}]}}";
public static ObjectMapper mapper = new ObjectMapper();
public static class User {
public String name;
@Override
public String toString() {
return "User{name='" + name + "'}";
}
}
static class Data {
@JsonProperty("d")
public Results d;
}
static class Results {
@JsonProperty("results")
public List<User> results;
}
static class MyList extends ArrayList<User> {
@JsonIgnore
@Override
public boolean isEmpty() {
return super.isEmpty();
}
}
public static void main(String[] args) throws IOException {
/********************* TEST1 ****************************/
test(() -> {
Data data = mapper.readerFor(new TypeReference<Data>() {
}).readValue(json);
Results result =data.d;
List<User> users = result.results;
},"readerFor()");
/********************* TEST2 ****************************/
test(() -> {
Results result = mapper.readerFor(new TypeReference<Results>() {
}).withRootName("d").readValue(json);
List<User> users = result.results;
},"readerFor().withRootName");
/********************* TEST3 ****************************/
test(() -> {
List<User> users = mapper.readerFor(
new TypeReference<List<User>>() {
}).readValue(mapper.readTree(json).get("d").get("results"));
},"readerFor().readValue(readTree)");
/********************* TEST4 ****************************/
test(() -> {
List<User> users = mapper.convertValue(
mapper.readTree(json).get("d").get("results"),
new TypeReference<List<User>>() {
});
},"convertValue(readTree)");
/********************* TEST5 ****************************/
JsonFactory jsonFactory = new JsonFactory();
jsonFactory.setCodec(mapper);
test(() -> {
List<User> array = new ArrayList<>();
JsonParser p = jsonFactory.createParser(json);
JsonToken curr;
while((curr = p.nextToken()) != null)
//this is just hardcoded version, usually you check for every tocken and act accordingly
//we just need to find array
if (curr == JsonToken.START_ARRAY){
while(p.nextToken() != JsonToken.END_ARRAY){
array.add(p.readValueAs(User.class));
}
}
},"custom inplace parser");
/********************* TEST6 ****************************/
//some setup needed for custom deserializer
SimpleModule module = new SimpleModule();
module.addDeserializer(MyList.class, new MyObjectDeserializer());
mapper.registerModule(module);
test(() -> {
List<User> users = mapper.readValue(json, MyList.class);
},"custom deserializer");
}
public static class MyObjectDeserializer extends JsonDeserializer<MyList>{
@Override
public MyList deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken curr;
MyList array = new MyList();
while((curr = p.nextToken()) != null)
//this is just hardcoded version, usually you check for every tocken and act accordingly
//we just need to find array
if (curr == JsonToken.START_ARRAY){
while(p.nextToken() != JsonToken.END_ARRAY){
array.add(p.readValueAs(User.class));
}
}
return array;
}
}
public interface Test {
void run() throws Exception;
}
public static void test(Test runnable, String testName) {
Runtime runtime = Runtime.getRuntime();
runtime.gc();
long startTime = System.currentTimeMillis();
try {
for (int i = 0; i < 10000000; i++)
runnable.run();
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println(testName + ": " +totalTime);
}
}
/*
Using 100000000 itterations
Results for simple json: "{"d": {"results": [{"name":"one"},{"name":"two"}]}}"
readerFor(): 53392 <= 2 root util objects
readerFor().withRootName: 55311 <= 1 root util object and withRootName option
readerFor().readValue(readTree): 113899
convertValue(readTree): 115614
custom inplace parser: 53194 <= JsonParser(same code as in custom deserializer)
custom deserializer: 56032
Using 1000000 itterations
For 5 huge users ( demo at the bottom of the page, 40-50 lines of json each, 6k lines total):
readerFor(): 26555
readerFor().withRootName: 25877
readerFor().readValue(readTree): 39733
convertValue(readTree): 41539
custom inplace parser: 28324
custom deserializer: 29000
Using 100000 itterations
For 100+ huge users ( demo at the bottom of the page, 40-50 lines of json each):
readerFor(): 64383
readerFor().withRootName: 63325
readerFor().readValue(readTree): 92239
convertValue(readTree): 99307
custom inplace parser: 69633
custom deserializer: 70230
Huge user demo is generated with https://www.json-generator.com/ looks like this:
{
"_id": "59c1c1eaecf0ac7a6fd552de",
"index": 0,
"guid": "6dc6ba8f-01c1-4669-a6a2-035b1240fba2",
"isActive": true,
"balance": "$1,442.02",
"picture": "http://placehold.it/32x32",
"age": 28,
"eyeColor": "green",
"name": "Charmaine Sears",
"gender": "female",
"company": "BESTO",
"email": "charmainesears@besto.com",
"phone": "+1 (903) 572-3249",
"address": "792 Harwood Place, Corinne, West Virginia, 1146",
"about": "Excepteur cupidatat velit duis enim irure amet. Commodo culpa nostrud eiusmod incididunt aliqua ut et adipisicing laborum et laborum. Irure non non esse amet exercitation deserunt Lorem mollit aliqua esse.\r\n",
"registered": "2015-03-19T08:06:51 -03:00",
"latitude": -55.062389,
"longitude": -27.841253,
"tags": [
"duis",
"aliquip",
"tempor",
"ad",
"voluptate",
"magna",
"eu"
],
"friends": [
{
"id": 0,
"name": "Nichole Sanford"
},
{
"id": 1,
"name": "Bray Short"
},
{
"id": 2,
"name": "Williams Kent"
}
],
"greeting": "Hello, Charmaine Sears! You have 7 unread messages.",
"favoriteFruit": "banana"
}
@varren
Copy link
Author

varren commented Sep 20, 2017

Memory tests: https://i.stack.imgur.com/bftGe.png
3 and 4 tests almost 2 times more memory then 1, 2, 4 ,5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment