Gson TypeAdapter slow deserialization

If you have been using Gson's TypeAdapter you might want to check your TypeAdapter's constructer to see if it causing performance issue.

Recently I received a report about the slow request on specified API endpoint.

Found out it was a performance issue on Gson deserialization, it took 3.059 seconds to deserialize a 3 KB JSON contains 30 objects in structure.

3 seconds on deserialization, INSANE.

The problem

original TypeAdapter definition and registration:

public class GenericItemDeserializer implements JsonDeserializer<GenericItem> {

    @Override
    public GenericItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Gson gson = new Gson();
        GenericItem item = null;

        ...

        return item;
    }
}
GsonBuilder gsonBuilder = new GsonBuilder();  
gsonBuilder.registerTypeAdapter(GenericItem.class, new GenericItemDeserializer());  
return gsonBuilder.create();  

The cause

Gson would create new TypeAdapter instance on each mapping process.

If you're an experienced developer, you might notice we initial new Gson instance on each TypeAdapter. What if Gson initialization is a resource consuming task?

It is.

The fix

Caching Gson instance at Gson builder.

In my case, deserialization time reduced from 3.059 to 0.072, which is a 420% boost.

public class GenericItemDeserializer implements JsonDeserializer<GenericItem> {  
    private Gson gson;

    public GenericItemDeserializer(Gson gson) {
        this.gson = gson;
    }

    @Override
    public GenericItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        GenericItem item = null;

        ...

        return item;
    }
}
Gson gson = new Gson();  
GsonBuilder gsonBuilder = new GsonBuilder();  
gsonBuilder.registerTypeAdapter(GenericItem.class, new GenericItemDeserializer(gson));  
return gsonBuilder.create();  
Is it thread-safe then?

Yes, Gson is thread-safe. Just cache it.

What about SimpleDateFormat at deserialization?

SimpleDateFormat initialization is resource consuming as well, though not dramatically impact the performance. But you should avoid it if you can. Notice that SimpleDateFormat is not thread-safe.