我们如何使用挂钩来提高性能?
Java文档说 Java文档
the Java Docs says Java Docs
公共类BufferedReader
扩展了Reader
public class BufferedReader extends Reader
从字符输入流中读取文本,缓冲字符,以提供对字符,数组和行的高效读取。
Reads text from a character-input stream, buffering characters so as to provide for the >efficient reading of characters, arrays, and lines.
缓冲区大小可能指定,或者可以使用默认大小。默认情况下,对于大多数用途而言,默认值都足够大。
The buffer size may be specified, or the default size may be used. The default is large >enough for most purposes.
通常,每个由Reader发出的读取请求都会导致相应的读取请求由基础字符或字节组成。流。因此,建议将> BufferedReader包裹在其read()操作可能会很昂贵的任何Reader上,例如> FileReaders和InputStreamReaders。例如,
In general, each read request made of a Reader causes a corresponding read request to be >made of the underlying character or byte stream. It is therefore advisable to wrap a >BufferedReader around any Reader whose read() operations may be costly, such as >FileReaders and InputStreamReaders. For example,
中的BufferedReader = new BufferedReader(new FileReader( foo.in));
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲来自指定文件的输入。如果不进行缓冲,则每次> read()或readLine()的调用都可能导致从文件中读取字节,将其转换为> character,然后返回,这可能会非常低效。
will buffer the input from the specified file. Without buffering, each invocation of >read() or readLine() could cause bytes to be read from the file, converted into >characters, and then returned, which can be very inefficient.
但是通过钩住Filereader,我们使用FileReader的read方法读取一次读取一个字符的文件,因此,如果我的文件包含2000字符FileReader首先将一次读取2000个字符,然后将其传输到缓冲区,然后我们将使用bufferedreader从缓冲区读取该字符,从而提高性能。仅使用FileReader可以做到这一点?
But by hooking Filereader we are using FileReader's read method to read file which reads one character at a time,So if my file contains 2000 characters FileReader firstly will read 2000 characters one at a time and transfer it to buffer and we will read that from buffer using bufferedreader so How it enhances performance.We could do it using FileReader only?
BufferedReader是使用缓冲区的常见示例。
The BufferedReader is a common example of using a buffer.
我们分解BufferedReader的read()方法( J7u51):
Let's decompose the read() method of BufferedReader (J7u51):
ensureOpen();
for (;;) {
if (nextChar >= nChars) {
fill();
if (nextChar >= nChars)
return -1;
}
如果满足以下条件,则会调用fill()方法(该方法调用底层的阅读器)仅当我们要求提供比以前的调用次数更多的字符时。
The fill() method (which calls the underlying reader) is invoked if and only if we ask for more characters than we've got from some previous calls.
if (skipLF) {
skipLF = false;
if (cb[nextChar] == '\n') {
nextChar++;
continue;
}
}
return cb[nextChar++];
}
在这里,我们只返回适当的值。
Here we just return the appropriate value.
所以BufferedReader总是多读些,以防您以后需要更多,然后,如果您真的想要更多,可以高效地给您更多。
So BufferedReader always "reads more in case you'd like more later" and then, if you really want more, can give you "the more" efficiently.
看看这个例子:
YourApp BufferedReader (bufferSize=10) FileReader
read(1 character) ->
buffer empty, load 10 characters -> disk latency 10 ms
<- return 10 characters
buffer filled with 10 characters
<- return 1 character, 9 remaining
in buffer
read(1 character) ->
<- return 1 character, 8 remaining
in buffer
.
.
.
read(1 character) ->
<- return 1 character, 0 remaining
in buffer
总计循环的执行时间为10毫秒+无关紧要的Java开销。
The total execution time of the loop is 10 milliseconds + insignificant Java overhead.
现在,将其与非缓冲版本进行比较:
Now, compare it with the unbuffered version :
YourApp FileReader
read(1 character) ->
disk latency 10 ms
<- return 1 character
read(1 character) ->
disk latency 10 ms
<- return 1 character
.
.
.
read(1 character) ->
disk latency 10 ms
<- return 1 character
造成的开销通过HDD调用的情况比以前的情况要大得多。
The overhead caused by the HDD calls is much bigger than in the previous case.