Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.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序列化在单次和多次转换时表现出较差的性能?_Java_Serialization - Fatal编程技术网

为什么我的Java序列化在单次和多次转换时表现出较差的性能?

为什么我的Java序列化在单次和多次转换时表现出较差的性能?,java,serialization,Java,Serialization,下面是我的基准代码。首先,我尝试序列化单个对象。然后我尝试做同样的事情一百万次。我原以为时间会按比例增加。相反,我得到了 1323048944117 1323048944131 1323048944117 1323048944210 14ms for one object 93ms for 1mil objects 这里发生了什么?我最担心的是单物体转换的时间,我希望能达到亚毫秒级 import java.io.ByteArrayOutputStream; import java.io.Ob

下面是我的基准代码。首先,我尝试序列化单个对象。然后我尝试做同样的事情一百万次。我原以为时间会按比例增加。相反,我得到了

1323048944117 1323048944131
1323048944117 1323048944210

14ms for one object
93ms for 1mil objects
这里发生了什么?我最担心的是单物体转换的时间,我希望能达到亚毫秒级

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Pojo implements Serializable {
    String blah = "11111111111111111111aaaaaaaaaaaaaaaaaaaa";
}

public class SerializeTest {
    public static void main(String[] args) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        Pojo pojo = new Pojo();
        long start = 0;
        long end1 = 0;
        try {
            out = new ObjectOutputStream(bos);
            start =  System.currentTimeMillis();
            out.writeObject(pojo);
            end1 = System.currentTimeMillis();
            for (int i=0;i<1000000;i++) {
                out.writeObject(pojo);
            }

        } catch (Exception ex) {

        }
        long end2 = System.currentTimeMillis();
        System.out.println(start + " " + end1);
        System.out.println(start + " " + end2);

    }
}
import java.io.ByteArrayOutputStream;
导入java.io.ObjectOutputStream;
导入java.io.Serializable;
类Pojo实现可序列化{
字符串blah=“11111111111111111 aaaaaaaaaaaaaaaa”;
}
公共类序列化测试{
公共静态void main(字符串[]args){
ByteArrayOutputStream bos=新建ByteArrayOutputStream();
ObjectOutputStream out=null;
Pojo Pojo=新Pojo();
长启动=0;
长端1=0;
试一试{
out=新对象输出流(bos);
start=System.currentTimeMillis();
out.writeObject(pojo);
end1=System.currentTimeMillis();

对于(int i=0;i仅供参考),您的第二次实际应为79毫秒

守则应改为:

System.out.println(end1+ " " + end2);

仅供参考,你的第二次应该是79毫秒

守则应改为:

System.out.println(end1+ " " + end2);

试着反向运行这两个。先运行一百万,然后运行一个,看看会发生什么。

试着反向运行这两个。先运行一百万,然后运行一个,看看会发生什么。

最终@duffmo是对的,你的结果98%是关于Java微测试的问题,而不是关于序列化的问题。他发布了一篇文章

另一个让您的测试感到困惑的因素是序列化是智能的。写入第一个对象会写入所有类和字段信息以及数据。同一对象实例的第二次到第n次写入仅写入对第一个对象的引用。第一个对象看起来约为120字节,其余每个对象仅为5字节。它也会快很多,因为它做的更少

我的测试在8毫秒内完成了第一个对象,在5毫秒内完成了接下来的1000个对象,然后在2000毫秒内完成了100万个对象。这主要向您展示了序列化的速度。它还向您展示了Java进行了一些神奇的实时优化,这些优化导致了速度曲线的急剧非线性


如果您试图进行一些序列化速度测试,我会让您的
Pojo
类生成一些随机数(或随机字符串)我会将1000个对象的序列化与100万个对象的序列化进行比较,以便更好地比较每个对象的序列化时间。要么这样做,要么在编写了1000个对象或其他东西后开始计时。例如,编写不同的对象会生成一个大约10倍但只需要5600毫秒的文件。

最终@duffmo会被删除他说,你的结果98%是关于用Java进行微测试的问题,而不是关于序列化的问题

另一个让您的测试感到困惑的因素是序列化是智能的。写入第一个对象会写入所有类和字段信息以及数据。同一对象实例的第二次到第n次写入仅写入对第一个对象的引用。第一个对象看起来约为120字节,其余每个对象仅为5字节。它也会快很多,因为它做的更少

我的测试在8毫秒内完成了第一个对象,在5毫秒内完成了接下来的1000个对象,然后在2000毫秒内完成了100万个对象。这主要向您展示了序列化的速度。它还向您展示了Java进行了一些神奇的实时优化,这些优化导致了速度曲线的急剧非线性


如果您试图进行一些序列化速度测试,我会让您的
Pojo
类生成一些随机数(或随机字符串)我会将1000个对象的序列化与100万个对象的序列化进行比较,以便更好地比较每个对象的序列化时间。要么这样,要么在写入1000个对象或其他对象后开始计时。例如,写入另一个对象会生成一个大约10倍但只需要5600毫秒的文件。

创建一个新的“pojo”对象t每次发送。您可能还希望在每个pojo实例中为“blah”指定不同的值。例如“”+Math.random()


我想你会看到一百万的性能更像你所期望的。IIRC当你一次又一次地将同一个对象序列化到同一个流中时,Java库会将它缓存在字典中,只会将一个“引用”发送回最初发送的对象。这就是为什么你看到百万pojo st的速度如此之快ream.

创建一个新的“pojo”对象以每次发送。您可能还希望在pojo的每个实例中为“blah”设置不同的值。例如“”+Math.random()


我想你会看到一百万的性能更像你所期望的。IIRC当你一次又一次地将同一个对象序列化到同一个流中时,Java库会将它缓存在字典中,只会将一个“引用”发送回最初发送的对象。这就是为什么你看到百万pojo st的速度如此之快ream.

阅读以下内容:@duffymo-这应该是答案…它被移动到评论,因为如此认为它“微不足道”。阅读以下内容:@duffymo-这应该是答案…它被移动到评论,因为如此认为它“微不足道”。作为一个评论会更好。这并不能真正解决他的问题。抱歉@Gray,但我还不能评论!!!我刚刚注册,拥有17个声誉。这是我提到这一点的唯一方式。请随意将其纳入您的答案中;)别担心。忘了吧。这最好是一个评论。它并没有真正解决他的问题。抱歉@Gray,但我还不能评论!!!我刚刚注册,有17个声誉。这是我唯一能提到这一点的方式。请随意将其纳入你的答案中;)别担心。忘了这一点。