BufferedReader和FileReader read()性能-大文本文件

时间:2018-12-23 09:30:29

标签: java io bufferedreader filereader

我正在使用以下2条代码来读取大文件。

使用FileReader

File file = new File("/Users/Desktop/shakes.txt");
FileReader reader = new FileReader(file);

int ch;
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    System.out.print((char) ch);
}
long end = System.currentTimeMillis();

以下使用BufferedReader

File file = new File("/Users/Desktop/shakes.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));

int ch;
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    System.out.print((char) ch);
}
long end = System.currentTimeMillis();

BufferedReader的文档进行操作:

  

因此,建议将BufferedReader包裹在其read()操作可能会很昂贵的任何Reader上,例如FileReaders和InputStreamReaders。如果不进行缓冲,则每次调用read()或readLine()都会导致从文件中读取字节,将其转换为字符,然后返回,这可能会非常低效。

鉴于此文档以及BufferedReader类的默认缓冲区大小8192,使用BufferedReader读取文件的总时间是否应该更快?目前,这两段代码都在我的计算机上运行〜3000ms。但是,如果我在BufferedReader中使用'readLine',则性能会大大提高(〜200ms)。

对我所缺少的东西有什么想法?难道不希望即使使用'read()'方法,BufferedReader的性能也要比从FileReader读取的性能更好吗?

2 个答案:

答案 0 :(得分:2)

使用BufferedReader确实比仅使用FileReader更快。

我在计算机上使用以下文本文件https://norvig.com/big.txt(6MB)执行了您的代码。

  • 初始结果显示的时间大致相同。每个大约17秒。
  • 但是,这是因为System.out.print()是瓶颈(在循环内)。如果不打印,使用BufferedReader的结果快4倍。 200ms与50ms。 (与之前的17秒进行比较)

换句话说,基准测试时请勿使用System.out.print()

示例

使用StringBuilder可以改善基准。

File file = new File("/Users/Desktop/shakes.txt");
FileReader reader = new FileReader(file);

int ch;
StringBuilder sb = new StringBuilder();
long start = System.currentTimeMillis();
while ((ch = reader.read()) != -1) {
    //System.out.print((char) ch);
    sb.append((char) ch);
}
long end = System.currentTimeMillis();

System.out.println(sb);

上面的代码提供相同的输出,但执行速度更快。使用BufferedReader时,它将准确显示速度差异。

答案 1 :(得分:0)

  

对我所缺少的东西有什么想法?

一次从BufferedReader读取文件字符应该比FileReader更快。 (数量级!)所以我怀疑问题出在您的基准测试中。

  1. 您的基准测试正在衡量读取文件并将其写入标准输出的能力。因此,基本上,写入文件的开销会使您的性能数字失真。并且,如果将输出写入“控制台”,则这些开销包括将字符绘制到屏幕上并进行滚动的开销。

  2. 您的基准测试不考虑虚拟机启动开销。

  3. 您的基准测试(显然)没有起到文件缓存的作用。 (第一次读取文件时,将从磁盘读取该文件。如果不久之后再次读取该文件,则可能是 从操作系统缓存在内存中的文件副本中读取。会更快。)