有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

性能为什么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内置序列化实际上很慢


共 (5) 个答案

  1. # 1 楼答案

    有点旧的帖子,但我发现做自己的原生方式更好。在所附的图像中,创建模型对象的本机方式与使用Gson的方式不同。每一次土生土长的结果都更好。[尝试使用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;
    

    结果:

    enter image description here

  2. # 2 楼答案

    Java内置的内部化测试中有很多对象创建,这可能是一个很大的开销。你能试着把new Gson()放到循环中,然后再运行一次吗。我仍然认为Java内置函数的速度会较慢,因为它比Gson复制更多字节,创建更多对象

    更新

    我在我的机器上运行了你的代码,没有任何修改,结果证明Gson比Java内置序列化慢得多

    Serialization cost: 21163ms
    Gson cost: 72636ms
    
  3. # 3 楼答案

    这是因为你在比较苹果和橙子

    在Gson测试中,您将创建一个Gson实例,并测量将N个对象序列化到该实例的时间

    在序列化测试中,您正在测量创建N个ObjectOutputStreams和N个ObjectInputStreams,并序列化一个对象的时间

    尝试一个有效的比较。你可能会大吃一惊