我有一段代码将输出流拆分到两个目标。他们都将去一个文件,但是第二个目的地将通过一个过滤器。我试图弄清楚为什么只包装一个FilterOutputStream而不覆盖任何方法会增加巨大的性能损失。



我创建了一个358 MB的文件:

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的源代码,但没有看到任何会造成如此巨大损失的内容。

有人可以解释可能导致此问题的原因吗?

最佳答案

之所以比较慢,是因为FilterOutputStream中的默认实现会禁用块处理,并通过write(int b)方法一次发送所有字节。

这是documented


  请注意,此方法不会使用相同的参数调用其基础输入流的write方法。 FilterOutputStream的子类应提供此方法的更有效实现。

关于java - Java FilterOutputStream增加了性能损失,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47721200/

10-09 03:54