Java PrintStream是缓冲的,但flush不会降低性能,BufferedOutputStream会提高性能

Java PrintStream是缓冲的,但flush不会降低性能,BufferedOutputStream会提高性能,java,performance,buffer,Java,Performance,Buffer,我认为,由于PrintStream是缓冲的,通过在每个print()之后添加一个flush操作,速度性能应该会显著降低,但它根本没有降低,如下面的代码段所示 此外,将PrintStream包装在BufferedOutputStream周围可以将性能提高10倍以上——这意味着PrintStream没有被缓冲 PrintStream是否真的没有缓冲,或者它是否有一个非常小的缓冲区,或者是否有其他解释说明为什么它不能提供缓冲流所期望的速度提升 // PrintStream is buff

我认为,由于PrintStream是缓冲的,通过在每个print()之后添加一个flush操作,速度性能应该会显著降低,但它根本没有降低,如下面的代码段所示

此外,将PrintStream包装在BufferedOutputStream周围可以将性能提高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);
//PrintStream已缓冲,但需要4228毫秒才能完成
长启动=System.currentTimeMillis();
try(PrintStream ps=newprintstream(newfileoutputstream(“1.txt”))
{
对于(int i=0;i<1_000;i++){
ps.print(i+);
}
}
长时间停止=System.currentTimeMillis();
系统输出打印LN(停止-启动);
//PrintStream是缓冲的,但是自动刷新需要4140ms才能完成,没有降级的速度意味着刷新什么也没做
start=System.currentTimeMillis();
try(PrintStream os=newprintstream(newfileoutputstream(“1.txt”))
{
对于(int i=0;i<1_000;i++){
操作系统打印(i+“”);
os.flush();
}
}
停止=System.currentTimeMillis();
系统输出打印LN(停止-启动);
//PrintStream作为BufferedOutputStream显式缓冲,运行速度很快:202ms
start=System.currentTimeMillis();
try(PrintStream os=newprintstream(newbufferedoutputstream(newfileoutputstream(“1.txt”)))
{
对于(int i=0;i<1_000;i++){
操作系统打印(i+“”);
}
}
停止=System.currentTimeMillis();
系统输出打印LN(停止-启动);
当内部被“缓冲”时,write方法会将内部缓冲区刷新到每个服务器上的底层流。因此,在前两个示例中,每个
write()
最终都会遇到FileOutputStream。在第三个场景中,您将获得实际的缓冲,其中写入只会周期性地命中FileOutputStream


如果您使用自己的底层流而不是FileOutputStream,您将看到前两种情况将导致约1000000个对流的写调用,而最后一种情况将导致更少的调用(基于缓冲区大小).

@jtahlborn我的问题是假设PrintStream是按源代码中的说明进行缓冲的……我的问题是为什么它不像BufferedOutputStream那样提高性能。我猜我误读了,我以为你在问它是否被缓冲了。非常有趣……那么,如果打印流总是被刷新,它在什么意义上有缓冲区呢?@Jonathan实际上没有。内部“缓冲区”实际上只是用来处理字符到字节的转换。老实说,PrintStream实际上是一个“遗留”类,在
System.out
之外的实践中,您不会真正使用它。它所做的一切都是通过一些较新的流实现来完成的。jtahlborn和@Jonathan我想知道为什么PrintStream有自己的缓冲区?你是说它的缓冲区就是它的
BufferedWriter
字段
textOut
中的缓冲区吗?我的问题现在在帖子里