我有一段代码将输出流分成两个目的地。他们都要去一个文件,但第二个目的地将通过一个过滤器。我试图找出为什么简单地包装FilterOutputStream而不覆盖任何方法会增加巨大的性能损失。
我创建了一个358兆字节的文件:
dd if=/dev/zero of=dummyfile.txt count=700000 bs=512
将此代码反对它:
private OutputStream getFilteredStream(OutputStream out1, OutputStream out2) {
return new TeeOutputStream(out1, new FilterOutputStream(out2));
}
private OutputStream getDestination(String name) {
return new BufferedOutputStream(new FileOutputStream(new File(name)));
}
...
InputStream in = new FileInputStream(new File("dummyfile.txt"));
OutputStream out = getFilteredStream(getDestination("dest1"), getDestination("dest2"));
long start = System.currentTimeMillis();
IOUtils.copy(in, out);
out.flush();
long end = System.currentTimeMillis();
System.err.println(((end - start) / 1000.0) + " seconds");
// close the files
结果:
1.672 seconds
如果我删除FilterOutputStream ...
private OutputStream getFilteredStream(OutputStream out1, OutputStream out2) {
return new TeeOutputStream(out1, out2);
}
...再次运行,结果是:
0.797 seconds
我期望在使用FilterOutputStream时性能下降,但我不希望惩罚加倍,特别是在没有覆盖任何方法时。我查看了FilterOutputStream的源代码,但没有看到任何会导致如此巨大损失的内容。
有人可以解释可能导致此问题的原因吗?
答案 0 :(得分:4)
速度较慢,因为FilterOutputStream
中的默认实现会禁用块处理,并通过write(int b)
方法一次发送所有字节。
这是documented:
请注意,此方法不会使用相同的参数调用其基础输入流的write方法。 FilterOutputStream的子类应该提供更有效的方法实现。