Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java内置序列化比Gson更糟糕?_Java_Performance_Serialization_Gson - Fatal编程技术网

为什么java内置序列化比Gson更糟糕?

为什么java内置序列化比Gson更糟糕?,java,performance,serialization,gson,Java,Performance,Serialization,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 sta

我认为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();
    }
}
我的计算机中的结果:

Serialization cost: 12339ms
Gson cost: 3971ms
Gson版本比“序列化”版本快得多。为什么


我的测试代码有什么问题吗,或者Java内置序列化实际上很慢?

Java内置序列化相当慢。供参考:


但是,在Java内置的内部化测试中有很多对象创建,这可能是一个很大的开销。您能否尝试将
new Gson()
放入循环中并再次运行。我仍然认为Java内置函数会更慢,因为它比Gson复制更多的字节,创建更多的对象

更新

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

Serialization cost: 21163ms
Gson cost: 72636ms

可能是因为内置序列化在类的实例首次写入流时将类描述写入流。编写单个
用户
对象时,可以衡量
用户
类描述构造和序列化+实例序列化的成本。在编写同一类的一系列对象时,内置序列化似乎更有效


参考资料:

因为你在比较苹果和橙子

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

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


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

这篇文章有点老,但我发现,做自己的本族主义方式更好。在附加的图像中,创建模型对象的本机方式与使用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;
InputStream is=newfileinputstream(zippers.extFile+“/airports.json”);
int size=is.available();
字节[]缓冲区=新字节[大小];
is.read(缓冲区);
is.close();
json=新字符串(缓冲区,“UTF-8”);
ArrayList=新建ArrayList();
日期d=新日期();
长s=d.getTime();
JSONArray JSONArray=新JSONArray(json);
int len=jsonArray.length();

对于(int i=0;i)您的对象太小了,所以您实际上只测量了开销!没错。这两个测试是不可比较的。+1对
available()
的典型误用。请参阅Javadoc。不清楚您所说的“native”是什么意思。我指的是JAVA方式。这部分代码复制到了某个地方
            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;