【发布时间】:2023-03-07 04:03:01
【问题描述】:
我知道使用 BufferedReader(包装 FileReader)比使用 BufferedInputStream(包装 FileInputStream)要慢得多,因为必须将原始字节转换为字符。但我不明白为什么它这么慢!这是我正在使用的两个代码示例:
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] byteBuffer = new byte[bufferSize];
int numberOfBytes;
do {
numberOfBytes = inputStream.read(byteBuffer, 0, bufferSize);
} while (numberOfBytes >= 0);
}
finally {
inputStream.close();
}
和:
BufferedReader reader = new BufferedReader(new FileReader(filename), bufferSize);
try {
char[] charBuffer = new char[bufferSize];
int numberOfChars;
do {
numberOfChars = reader.read(charBuffer, 0, bufferSize);
} while (numberOfChars >= 0);
}
finally {
reader.close();
}
我尝试过使用各种缓冲区大小的测试,所有这些测试都包含一个 150 兆字节的文件。以下是结果(缓冲区大小以字节为单位;时间以毫秒为单位):
Buffer Input
Size Stream Reader
4,096 145 497
8,192 125 465
16,384 95 515
32,768 74 506
65,536 64 531
可以看出,BufferedInputStream 的最快时间(64 毫秒)比 BufferedReader 的最快时间(465 毫秒)快七倍。正如我上面所说,我没有显着差异的问题。但是这么大的差异似乎不合理。
我的问题是:是否有人对如何提高 BufferedReader 的性能或替代机制提出建议?
【问题讨论】:
-
我认为最可能的解释是您的基准测试存在缺陷;例如您没有正确考虑 JVM 预热效果。请发布完整的内容。
-
@StephenC 或者磁盘缓存?
-
您在比较苹果和橙子——第二个测试涉及将字节转换为
char,而第一个不这样做。如果您需要char数据,请使用Reader;如果您需要字节,请使用InputStream。我想你会发现最快的将是BufferedReader包裹InputStreamReader包裹BufferedInputStream包裹FileInputStream。另请参阅this thread,了解如何编写基准测试。 -
结果也可能取决于所使用的字符编码。
-
没有看到你的实际代码,我无法给你完整的解释。但我认为这的主要原因是 1)您报告的时间对我来说似乎不可信,以及 2)您没有对 JVM 预热理论做出回应……这表明您不了解它的重要性。只需发布代码......这样我们就可以看到您实际在做什么,并尝试重现它。
标签: java performance bufferedreader bufferedinputstream