为什么我的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个声誉。这是我唯一能提到这一点的方式。请随意将其纳入你的答案中;)别担心。忘了这一点。