我们如何使用挂钩来提高性能?

问题描述:

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.