我认为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();
}
}
作为java bean的类User
:
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内置序列化实际上是否很慢?
答案 0 :(得分:5)
Java内置序列化 非常慢。供参考:https://github.com/eishay/jvm-serializers/wiki
但是,有quite a few ways in which your benchmark should be improved for more-accurate results.
答案 1 :(得分:3)
可能是因为当类的实例首次写入流时,内置序列化会将类描述写入流中。编写单个 User
对象,可以衡量User
类描述构造和序列化+实例序列化的成本。在编写同一类的一系列对象时,内置序列化似乎更有效。
参考:http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#5552
答案 2 :(得分:2)
Java内置非编译测试中有很多对象创建,这可能是一个重要的开销。你可以尝试将new Gson()
置于循环中并再次运行。我仍然希望Java内置函数更慢,因为它复制更多字节并创建比Gson更多的对象。
<强>更新强>
我在我的机器上使用无修改运行代码,结果发现Gson比Java内置序列化慢得多。
Serialization cost: 21163ms
Gson cost: 72636ms
答案 3 :(得分:2)
这是因为你将苹果与橙子进行比较。
在你的Gson测试中,你正在创建一个Gson实例并测量将N个对象序列化为它的时间。
在序列化测试中,您将测量创建N ObjectOutputStreams和N ObjectInputStreams的时间,并序列化一个对象。
尝试有效的比较。你可能会感到非常惊讶。
答案 4 :(得分:-1)
有点老帖子,但我发现的是做自己的本土方式更好。在附加图像中,创建模型对象的Native方式与Using Gson相比。每次Native方式结果都更好。 [尝试了27000个Json对象的27000个Json数组。]
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;
结果: