让 BufferedReader 流保持打开状态是否有任何性能优势?
Are there any performance benefits to leaving BufferedReader stream open?
在我提出问题之前,我完全知道让输入流保持打开状态会导致内存泄漏,因此这样做是不好的做法。
考虑以下先决条件:
- 只需要读取一个文件
- 相关文件是包含数据行的文本文件
- 此文件很大:50MB 或更多
- 文件在测试期间被读取了很多很多次运行
我问的原因是在我的测试自动化套件中,需要一遍又一遍地调用同一个文件来验证某些数据字段。
在当前状态下,数据 reader 函数打开 BufferedReader
流,reads/returns 数据,然后关闭流。
但是,由于文件大小和文件被读取的次数,我不知道让流打开是否会有好处。老实说,我根本不知道文件大小是否会影响流的打开。
总而言之,鉴于上面列出的先决条件,打开 BufferedReader
输入流是否会提高整体性能?内存泄漏是否仍然可能?
如果您有足够的内存来执行此操作,那么您可能会通过将整个文件读入 StringBuilder
,将其转换为 String
,然后重复从String
通过 StringReader
.
但是,您可能需要 6 倍或更多字节的(空闲)堆 space 作为文件的大小。
- 2 x 允许
byte
-> char
扩展
- 3 x 因为
StringBuilder
缓冲区随着它的增长而扩展的方式。
您可以通过将文件作为字节(而不是字符)保存在内存中并读入恰好大小的 byte[]
来保存 space。但是每次从 byte[]
中读取时,您都需要重复字节 -> 字符解码。
如果您需要终极性能,您应该对替代方案进行基准测试。
并考虑使用 Buffer
来减少复制。
同意你的想法。与关闭和重新打开相比,保持 BufferedReader
打开并使用 mark
和 reset
会给你一个小的加速。但是你的文件越大,相对而言加速比就越小。对于 50GB 的文件,我怀疑加速是微不足道的。
是的,理论上不关闭流可以提高性能,因为对象不会触发垃圾回收
假设您不是 de-referencing BufferedReader。此外,不需要同步底层资源。查看类似的答案:Performance hit opening and closing filehandler?
但是,不关闭 BufferedReader 将导致 memory leak and you'll see heap increase。
我建议就像其他人在评论和答案中所说的那样,将文件读入内存并使用它。一个 50MB 的文件并没有那么多,再加上从内存中读取一次字符串的性能将比 re-reading 一个文件高得多。
在我提出问题之前,我完全知道让输入流保持打开状态会导致内存泄漏,因此这样做是不好的做法。
考虑以下先决条件:
- 只需要读取一个文件
- 相关文件是包含数据行的文本文件
- 此文件很大:50MB 或更多
- 文件在测试期间被读取了很多很多次运行
我问的原因是在我的测试自动化套件中,需要一遍又一遍地调用同一个文件来验证某些数据字段。
在当前状态下,数据 reader 函数打开 BufferedReader
流,reads/returns 数据,然后关闭流。
但是,由于文件大小和文件被读取的次数,我不知道让流打开是否会有好处。老实说,我根本不知道文件大小是否会影响流的打开。
总而言之,鉴于上面列出的先决条件,打开 BufferedReader
输入流是否会提高整体性能?内存泄漏是否仍然可能?
如果您有足够的内存来执行此操作,那么您可能会通过将整个文件读入 StringBuilder
,将其转换为 String
,然后重复从String
通过 StringReader
.
但是,您可能需要 6 倍或更多字节的(空闲)堆 space 作为文件的大小。
- 2 x 允许
byte
->char
扩展 - 3 x 因为
StringBuilder
缓冲区随着它的增长而扩展的方式。
您可以通过将文件作为字节(而不是字符)保存在内存中并读入恰好大小的 byte[]
来保存 space。但是每次从 byte[]
中读取时,您都需要重复字节 -> 字符解码。
如果您需要终极性能,您应该对替代方案进行基准测试。
并考虑使用 Buffer
来减少复制。
同意你的想法。与关闭和重新打开相比,保持 BufferedReader
打开并使用 mark
和 reset
会给你一个小的加速。但是你的文件越大,相对而言加速比就越小。对于 50GB 的文件,我怀疑加速是微不足道的。
是的,理论上不关闭流可以提高性能,因为对象不会触发垃圾回收 假设您不是 de-referencing BufferedReader。此外,不需要同步底层资源。查看类似的答案:Performance hit opening and closing filehandler?
但是,不关闭 BufferedReader 将导致 memory leak and you'll see heap increase。
我建议就像其他人在评论和答案中所说的那样,将文件读入内存并使用它。一个 50MB 的文件并没有那么多,再加上从内存中读取一次字符串的性能将比 re-reading 一个文件高得多。