优化Java';用于小文件的NIO

优化Java';用于小文件的NIO,java,optimization,file-io,nio,Java,Optimization,File Io,Nio,我们有一个文件I/O瓶颈。我们有一个包含大量JPEG文件的目录,我们希望将它们作为电影实时读取。显然,这不是一种理想的格式,但这是一个原型对象跟踪系统,不可能更改格式,因为它们在代码的其他地方使用 从每个文件中,我们构建一个帧对象,这基本上意味着拥有一个缓冲图像和一个包含图像所有信息的显式bytebuffer 这方面的最佳策略是什么?数据位于SSD上,从理论上讲,SSD的读/写速率约为400Mb/s,但实际上使用naive实现每秒读取的文件不超过20个(3-4Mb/s): bufferedImg

我们有一个文件I/O瓶颈。我们有一个包含大量JPEG文件的目录,我们希望将它们作为电影实时读取。显然,这不是一种理想的格式,但这是一个原型对象跟踪系统,不可能更改格式,因为它们在代码的其他地方使用

从每个文件中,我们构建一个帧对象,这基本上意味着拥有一个缓冲图像和一个包含图像所有信息的显式bytebuffer

这方面的最佳策略是什么?数据位于SSD上,从理论上讲,SSD的读/写速率约为400Mb/s,但实际上使用naive实现每秒读取的文件不超过20个(3-4Mb/s):

bufferedImg = ImageIO.read(imageFile);[1]
byte[] data = ((DataBufferByte)bufferedImg.getRaster().getDataBuffer()).getData();[2]
imgBuf = ByteBuffer.wrap(data);
然而,Java为改进这一点提供了很多可能性。 (1) 频道。Esp文件通道 (2) 聚集/分散。 (3) 直接缓冲 (4) 内存映射缓冲区 (5) 多线程-使用一组可调用项同时访问多个文件。 (6) 将文件包装到单个大文件中。 (7) 其他我还没想到的事情

我只想知道是否有人对不同的选择进行了广泛的测试,并且知道什么是最佳的?我认为(3)是必须的,但我仍然希望尽可能优化单个文件的读取,并且不确定最佳策略

另外一个问题:在上面截取的代码中,JVM何时真正“命中磁盘”并读入文件内容,是[1]还是仅仅是一个“指向”对象的文件处理程序?懒洋洋地评估是有道理的,但我不知道ImageIO类的实现是如何工作的

ImageIO.read(imageFile)

当它返回BuffereImage时,我假设它将命中磁盘而不是文件处理程序。

我将获得额外奖励:
ImageIO
read()
方法返回之前读取所有数据。这是
buffereImage
合同的一部分,没有延迟评估。较旧的
java.awt.Image
使用消费者/生产者模式,但这也不是真正的“懒惰”…您可以查看创建由
ByteBuffer
支持的自定义
DataBuffer
的示例(
MappedFileBuffer
MappedImageFactory
)。不过,我不确定这会有多大帮助。我相信多线程是你的最佳选择。一定要考虑到你的瓶颈可能是java的IMAIIO类将文件的字节转换成缓冲区对象的处理。如果是这种情况,那么更改用于从磁盘获取字节的方法可能对优化没有多大帮助。我从未使用过,但知道s。如果您的应用程序运行在哪台机器上,可能值得调查。大多数人没有意识到,但您通常可以通过设置(默认为
true
)从
ImageIO
)获得免费的性能改进。这将禁用
ImageIO
使用的磁盘缓存,而是使用内存缓存。