我预计,由于PrintStream是缓冲的,通过在每次print()之后添加刷新操作,速度性能会显着下降,但它根本没有,如下面的代码片段所示。
此外,在BufferedOutputStream周围打包PrintStream可将性能提高10倍以上 - 这意味着PrintStream不会被缓冲。
PrintStream是否真的没有缓冲,或者它是否有一个非常小的缓冲区,或者是否有其他解释为什么它不能提供缓冲流预期的速度提升?
// PrintStream is buffered but takes 4228ms to complete
long start = System.currentTimeMillis();
try (PrintStream ps = new PrintStream(new FileOutputStream("1.txt") ))
{
for (int i = 0; i < 1_000_000; i++) {
ps.print(i + " ");
}
}
long stop = System.currentTimeMillis();
System.out.println(stop - start);
// PrintStream is buffered, but with auto-flush takes 4140ms to complete, no degraded speed implying flush did nothing
start = System.currentTimeMillis();
try (PrintStream os = new PrintStream(new FileOutputStream("1.txt") ))
{
for (int i = 0; i < 1_000_000; i++) {
os.print(i + " ");
os.flush();
}
}
stop = System.currentTimeMillis();
System.out.println(stop - start);
// PrintStream is buffered explicitly as a BufferedOutputStream and runs quickly: 202ms
start = System.currentTimeMillis();
try (PrintStream os = new PrintStream(new BufferedOutputStream(new FileOutputStream("1.txt")) ))
{
for (int i = 0; i < 1_000_000; i++) {
os.print(i + " ");
}
}
stop = System.currentTimeMillis();
System.out.println(stop - start);
答案 0 :(得分:2)
虽然内部是&#34;缓冲&#34;,但write方法会在每个write()上将内部缓冲区刷新到基础流。因此,在前两个示例中,每个write()
最终都会触及FileOutputStream。在第三种情况下,您将获得实际缓冲,其中写入仅定期访问FileOutputStream。
如果您使用自己的基础流而不是FileOutputStream,您会看到前两个场景将导致对您的流进行~1,000,000次写入调用,而最后一种情况将导致更少的调用(基于缓冲区大小)