Reputation: 198238
I thought the performance of Java built-in serialization should be good. Compare to Gson, it doesn't need to do the lexical analysis, it should be faster than Gson.
But in my test, the result is just the opposite. See my code:
package cleancode;
import com.google.gson.Gson;
import java.io.*;
public class SerializationPerformanceTest {
public static final int MAX_LOOP = 1000000;
public static void main(String[] args) throws Exception {
trySerialization();
tryGson();
}
private static void tryGson() {
long start = System.currentTimeMillis();
Gson gson = new Gson();
for (int i = 0; i < MAX_LOOP; i++) {
String json = gson.toJson(createUser());
gson.fromJson(json, User.class);
}
long end = System.currentTimeMillis();
System.out.println("Gson cost: " + (end - start) + "ms");
}
private static void trySerialization() throws IOException, ClassNotFoundException {
long start = System.currentTimeMillis();
for (int i = 0; i < MAX_LOOP; i++) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(byteStream);
stream.writeObject(createUser());
byte[] binary = byteStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(binary);
ObjectInputStream input = new ObjectInputStream(byteArrayInputStream);
input.readObject();
}
long end = System.currentTimeMillis();
System.out.println("Serialization cost: " + (end - start) + "ms");
}
private static User createUser() {
User user = new User();
user.setAaa(newValue());
user.setBbb(newValue());
user.setCcc(newValue());
user.setDdd(newValue());
user.setEee(newValue());
user.setFff(newValue());
user.setGgg(newValue());
return user;
}
private static String newValue() {
return "" + System.currentTimeMillis();
}
}
The class User
which is a java bean:
class User implements Serializable {
private String aaa;
private String bbb;
private String ccc;
private String ddd;
private String eee;
private String fff;
private String ggg;
String getAaa() {
return aaa;
}
void setAaa(String aaa) {
this.aaa = aaa;
}
String getBbb() {
return bbb;
}
void setBbb(String bbb) {
this.bbb = bbb;
}
String getCcc() {
return ccc;
}
void setCcc(String ccc) {
this.ccc = ccc;
}
String getDdd() {
return ddd;
}
void setDdd(String ddd) {
this.ddd = ddd;
}
String getEee() {
return eee;
}
void setEee(String eee) {
this.eee = eee;
}
String getFff() {
return fff;
}
void setFff(String fff) {
this.fff = fff;
}
String getGgg() {
return ggg;
}
void setGgg(String ggg) {
this.ggg = ggg;
}
}
The result in my computer:
Serialization cost: 12339ms
Gson cost: 3971ms
The Gson version is much faster than the "Serialization" one. Why?!
Is there anything wrong is my test code, or Java built-in serialization is actually slow?
Upvotes: 1
Views: 3345
Reputation: 912
Bit old post, but what i find is Native way of doing yourself is better. In the attached image, Native way of creating the model objects vs Using Gson. Every time Native way result was better. [Tried with 27000 Json array of 27000 Json objects.]
InputStream is = new FileInputStream(Zipper.extFile+"/airports.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
ArrayList<Displayable> list = new ArrayList<>();
Date d = new Date();
long s = d.getTime();
JSONArray jsonArray = new JSONArray(json);
int len = jsonArray.length();
for (int i=0;i<len;i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
Airport airport = new Airport();
airport.setIata(jsonObject.optString("iata"));
airport.setLon(jsonObject.optString("lon"));
airport.setIso(jsonObject.optString("iso"));
airport.setStatus(jsonObject.optInt("status"));
airport.setContinent(jsonObject.optString("continent"));
airport.setName(jsonObject.optString("name"));
airport.setType(jsonObject.optString("type"));
airport.setSize(jsonObject.optString("size"));
airport.setLat(jsonObject.optString("lat"));
list.add(airport);
}
Log.d("Time to build Java way","" + (new Date().getTime() - s));
long s1 = d.getTime();
Gson g = new Gson();
List<? extends Displayable> list1 = g.fromJson(json, new TypeToken<List<Airport>>(){}.getType());
Log.d("Time to build Gson way","" + (new Date().getTime() - s1));
Cache.getInstance().airportArrayList = list;
Result:
Upvotes: -1
Reputation: 310916
It it because you're comparing apples with oranges.
In your Gson test, you are creating a single Gson instance and measuring the time to serialize N objects to it.
In your Serialization test, you are measuring the time to create N ObjectOutputStreams and N ObjectInputStreams, and serialize one object.
Try a valid comparison. You might get quite a surprise.
Upvotes: 3
Reputation: 15283
Probably because built-in serialization writes class description into the stream, when an instance of the class is first written into the stream. Writing a single User
object, you measure the cost of User
class description construction and serialization + an instance serialization. Built-in serialization should seem more efficient on writing series of objects of the same class.
Reference: http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#5552
Upvotes: 3
Reputation: 8969
There are a lot of object creations in the test for Java built-inserialization and that is probably a significant overhead. Can you try to put new Gson()
inside the loop and run again. I still expect the Java built-in function to be slower because it copies more bytes and creates more objects than Gson.
Update
I ran your code with no modification on my machine and it turns out that Gson is much slower than Java built-in serialization.
Serialization cost: 21163ms
Gson cost: 72636ms
Upvotes: 2
Reputation: 359816
Java built-in serialization is quite slow. For reference: https://github.com/eishay/jvm-serializers/wiki
However, there are quite a few ways in which your benchmark should be improved for more-accurate results.
Upvotes: 5