[Java Performance] buffer I/O (Buffered I/O), javaperformance
Buffer I/O (Buffered I/O)
InputStream.read()
AndOutputStream.write()
The operation object is a single byte. Depending on the resources they access, using these methods may be quite slow.
For exampleFileInputStream.read()
The speed will be terrible. Because each call will access the kernel of the operating system to get 1 byte of data. In modern operating systems, the kernel usually uses buffer I/O implementation, so this operation does not trigger a disk read operation every time it is called. However, the buffer is in the kernel after all. Therefore, each call to this method means that an expensive system call will occur to obtain one byte in the kernel I/O buffer.
The same is true for writing data. Each callFileOutputStream.write()
Each method stores one of its own data in the buffer zone of the kernel. When the file is closed or the flush method is called, the kernel will write the buffer content to the disk.
For File-based Binary Data I/O, you must use BufferedInputStream or BufferedOutputStream to encapsulate the underlying File byte streams.
For File-based Character Data I/O, you must use BufferedReader or BufferedWriter to encapsulate the hidden stream of the underlying File.
In fact, the above best practices are not only limited to file I/O, but are almost applicable to other types of I/O. For example, the byte stream obtained through Socket (throughgetInputStream()
AndgetOutputStream()
Before using them, you must use the Buffering Filter Stream to encapsulate them.
However, there are still special cases. When the ByteArrayInputStream and ByteArrayOutputStream types are used, do not use the buffer filter stream for them. These two types will set a region in the memory as a buffer, so when you set a buffer filter stream for them, the data will be copied twice. Take ByteArrayInputStream as an example:
- Buffer from the kernel buffer to the buffer to filter the stream
- From buffer to ByteArrayInputStream
When other Filtering streams are involved, whether to use the buffer to filter the Stream requires specific analysis. For example, in a serialization example:
private void writeObject(ObjectOutputStream out) throws IOException { if (prices == null) { makePrices(); } out.defaultWriteObject();}protected void makePrices() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(prices); oos.close();}
Although ObjectOutputStream only sends one byte to the next Stream at a time, it makes no sense to use BufferedOutputStream when the next Stream is the final ByteArrayOutputStream. This will only increase the number of data copies, resulting in a reduction in performance.
However, when other filtering streams exist between ByteArrayOutputStream and ObjectOutputStream, it may be useful to filter buffered streams. For example, when you need to use a compression filter stream to compress the byte array:
private void writeObject(ObjectOutputStream out) throws IOException { if (prices == null) { makeZippedPrices(); } out.defaultWriteObject();}protected void makeZippedPrices() throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream zip = new GZIPOutputStream(baos); BufferedOutputStream bos = new BufferedOutputStream(zip); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(prices); oos.close(); zip.close();}
A BufferedOutputStream is added between GZIPOutputStream and ObjectOutputStream. The reason for this is that when GZIPOutputStream's operation object is a piece of data, the performance will be higher than when the operation object is a byte.
When you use an Encoder/Decoder stream to convert byte data and character data, you can use a buffer filter stream to encapsulate these data for better performance.
The following table shows whether to use the buffer to filter the effect of the stream on the final time during compression serialization/deserialization:
Operation |
Serialization time |
Deserialization time |
Unbuffered compression/Decompression |
60.3 s |
79.3 s |
Buffered compression/Decompression |
26.8 s |
12.7 s |
It can be seen that when a BufferedOutputStream is added between GZIPOutputStream and ObjectOutputStream, the performance is improved significantly.
Summary
InputStream.read()
AndOutputStream.write()
Because they only operate on one byte.
- When operating on the file stream, Socket stream, compressed stream, and character encoding stream, make sure that the buffer filter stream is used to encapsulate them.
What is the difference between the custom Array Buffer in java and BufferedInputStream or BufferedWriter?
I personally think these practices reflect the progress and development of data processing methods.
Using Direct byte [] is the most basic or the most primitive method. It is equal to inventing the wheel from 0.
Various Stream, Reader, Writer, iterator, Printer and so on are convenient for some conventional I/O processing, and are also a better solution for specific situations in practice. With some commonly used wheels, it is convenient to transport east and west. Various streams belong to Java's standard IO library.
After Java 5, a new IO Library (NIO) appears ). It provides convenience tools for large-capacity files, large-volume data reading and writing, and parallel multi-thread reading and writing. It is equivalent to directly providing a wheel car for you to move things.
The specific use depends on the actual situation and your ability to control basic knowledge and tools.
For operations in complex electromagnetic environments, the wheel cannot be repeatedly invented.
For daily cooking dishes, it is not recommended to use a knife to kill chickens.
Writter and Reader are character strings composed of char characters.
The basic Stream is for byte streams and byte strings.
In java, the BufferedInputStream class improves the input efficiency and adds input buffer power,
The concept of this buffer zone is abstract. In fact, we can understand this.
For operations without buffering, one byte is required for each read. Because I/O operations involving disks are much slower than memory operations, the streaming efficiency without buffering is very low.
A stream with buffer can read many bytes at a time, but is not written to the disk. It is only put in memory first. Write Data to the disk at one time when the buffer size is sufficient. This method can reduce the number of disk operations and increase the speed.