PrintStream被缓冲,但是刷新不会降低性能,并且BufferedOutputStream可以提高性能 [英] PrintStream is buffered, but flush does not degrade performance and BufferedOutputStream speeds up performance

查看:128
本文介绍了PrintStream被缓冲,但是刷新不会降低性能,并且BufferedOutputStream可以提高性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望由于对PrintStream进行了缓冲,因此,通过在每个print()之后添加刷新操作,速度性能应该会大大降低,但完全没有降低,如下面的代码片段所示。

I expected that since PrintStream is buffered, by adding a flush operation after every print(), the speed performance should degrade significantly, but it did not at all, as shown in the below code snippet.

此外,将PrintStream包裹在BufferedOutputStream周围可将性能提高10倍以上,这意味着PrintStream没有得到缓冲。

Furthermore, wrapping a PrintStream around a BufferedOutputStream improves performance by more than 10x -- implying that PrintStream is not buffered.

PrintStream确实是没有缓冲,或者它的缓冲区很小,或者是否还有其他解释说明为什么它不能提供缓冲流所期望的速度改进?

Is PrintStream really not buffered, or does it have a very small buffer, or is there some other explanation for why it does not afford the speed improvement expected from a buffered stream?

       // 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);


推荐答案

内部是缓冲的,但是写方法将每个 write()。因此,在您的前两个示例中,每个 write()最终都会达到FileOutputStream。在第三个场景中,您将获得 actual 缓冲,其中写入仅会定期命中FileOutputStream。

While the internals are "buffered", the write method flushes the internal buffers to the underlying stream on every write(). So in your first two examples, every write() is ultimately hitting FileOutputStream. In your third scenario, you are getting actual buffering, where writes are only periodically hitting the FileOutputStream.

如果您使用自己的基础流在FileOutputStream中,您会看到前两种情况将导致对您的流的〜1,000,000个写调用,而后一种情况将导致更少的调用(基于缓冲区大小)。

If you used your own underlying stream instead of FileOutputStream, you would see that the first two scenarios will result in ~1,000,000 write calls to your stream, whereas the last case will result in much fewer calls (based on the buffer size).

这篇关于PrintStream被缓冲,但是刷新不会降低性能,并且BufferedOutputStream可以提高性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆