PrintWriter vs PrintStream vs OutputStreamWriter timecosts

As you know, we have several tools in java for writing data to streams.
In this code example, I compared them by runtime.
Can someone explain this for sure? Thanks.
Here is the code:

import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; public class IOtests { public static void main(String[] args) throws Exception { char[] chars = new char[100]; byte[] bytes = new byte[100]; for (int i = 0; i < 100; i++) { chars[i] = (char) i; bytes[i] = (byte) i; } OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream( "output.txt")); long a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (char j : chars) out.write(j); System.out.println("OutputStreamWriter writing characters: " + (System.currentTimeMillis() - a)); out = new OutputStreamWriter(new FileOutputStream("output.txt")); a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (byte j : bytes) out.write(j); System.out.println("OutputStreamWriter writing bytes: " + (System.currentTimeMillis() - a)); PrintStream out1 = new PrintStream("output.txt"); a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (char j : chars) out1.write(j); System.out.println("PrintStream writing characters: " + (System.currentTimeMillis() - a)); out1 = new PrintStream("output.txt"); a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (byte j : bytes) out1.write(j); System.out.println("PrintStream writing bytes: " + (System.currentTimeMillis() - a)); PrintWriter out2 = new PrintWriter("output.txt"); a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (char j : chars) out2.write(j); System.out.println("PrintWriter writing characters: " + (System.currentTimeMillis() - a)); out1 = new PrintStream("output.txt"); a = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) for (byte j : bytes) out2.write(j); System.out.println("PrintWriter writing bytes: " + (System.currentTimeMillis() - a)); } } 

Results:

Output characters WriteStreamWriter: 4141
OutputStreamWriter writes bytes: 3546
Writing PrintStream characters: 86516
PrintStream Recording Pixels: 70484
PrintWriter Writing Characters: 938
PrintWriter writes bytes: 2484

Note that all times are in milliseconds.

+6
source share
1 answer

I brought my question to the point:

 public class Test { static byte[] bytes = new byte[10_000_000]; static { for (int i = 0; i < bytes.length; i++) bytes[i] = (byte) (i%100+32); } public static void main(String[] args) throws Exception { writer(true); writer(false); stream(true); stream(false); } static void writer(boolean flush) throws IOException { Writer out = new FileWriter("output.txt"); long a = System.currentTimeMillis(); for (byte j : bytes) { out.write(j); if (flush) out.flush(); } out.close(); System.out.println("FileWriter with" + (flush? "":"out") + " flushing: " + (System.currentTimeMillis() - a)); } static void stream(boolean flush) throws IOException { OutputStream out = new FileOutputStream("output.txt"); long a = System.currentTimeMillis(); for (byte j : bytes) { out.write(j); if (flush) out.flush(); } out.close(); System.out.println("FileOutputStream with" + (flush? "":"out") + " flushing: " + (System.currentTimeMillis() - a)); } } 

Notes:

  • proper closure of resources upon completion;
  • the double cycle is replaced by one cycle, but a large array;
  • Avoid writing control characters to avoid autorun behavior
  • only an array of bytes is used, since in all cases you only check one method: write(int) . Therefore, it doesn’t matter if you use bytes or characters,
  • everything except FileWriter and a FileOutputStream , because all other cases come down to these two:
  • testing both the recording script and the output stream in two modes: reset after each recording and generally no reset before closing.

Now, when you run this, you will get the result as follows:

 FileWriter with flushing: 28235 FileWriter without flushing: 828 FileOutputStream with flushing: 23984 FileOutputStream without flushing: 23641 

So what is the lesson?

  • all authors are buffered because internally they are delegated by StreamEncoder , which itself is buffered;
  • FileOutputStream not buffered;
  • unbuffered byte by byte writing is very slow.

Good practice requires that you always do buffered writing: either using buffered receivers, or maintaining an explicit buffer on your side.

+3
source

Source: https://habr.com/ru/post/952462/


All Articles