性能为什么java内置序列化比Gson差?
我认为Java内置序列化的性能应该很好。与Gson相比,它不需要进行词法分析,应该比Gson更快
但在我的测试中,结果正好相反。查看我的代码:
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();
}
}
类User
是一个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;
}
}
在我的电脑中的结果:
Serialization cost: 12339ms
Gson cost: 3971ms
Gson版本比“序列化”版本快得多。为什么
我的测试代码有什么问题吗,或者Java内置序列化实际上很慢
# 1 楼答案
有点旧的帖子,但我发现做自己的原生方式更好。在所附的图像中,创建模型对象的本机方式与使用Gson的方式不同。每一次土生土长的结果都更好。[尝试使用27000个Json对象的27000个Json数组。]
结果:
# 2 楼答案
Java内置的内部化测试中有很多对象创建,这可能是一个很大的开销。你能试着把
new Gson()
放到循环中,然后再运行一次吗。我仍然认为Java内置函数的速度会较慢,因为它比Gson复制更多字节,创建更多对象更新
我在我的机器上运行了你的代码,没有任何修改,结果证明Gson比Java内置序列化慢得多
# 3 楼答案
这是因为你在比较苹果和橙子
在Gson测试中,您将创建一个Gson实例,并测量将N个对象序列化到该实例的时间
在序列化测试中,您正在测量创建N个ObjectOutputStreams和N个ObjectInputStreams,并序列化一个对象的时间
尝试一个有效的比较。你可能会大吃一惊
# 4 楼答案
Java内置序列化非常慢。供参考:https://github.com/eishay/jvm-serializers/wiki
然而,有quite a few ways in which your benchmark should be improved for more-accurate results.
# 5 楼答案
可能是因为当类的实例第一次写入流时,内置序列化会将类描述写入流。通过编写一个对象,可以衡量
User
类描述构造和序列化+实例序列化的成本。在编写同一类的一系列对象时,内置序列化似乎更有效参考:http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#5552