gpt4 book ai didi

java - 确定合适的缓冲区大小

转载 作者:搜寻专家 更新时间:2023-11-01 03:07:59 25 4
gpt4 key购买 nike

我正在使用 ByteBuffer.allocateDirect() 分配一些缓冲内存以将文件读入内存,然后最终对文件字节进行哈希处理并从中获取文件哈希 (SHA)。输入文件的大小范围很大,从几 KB 到几 GB 不等。

我已经阅读了几个关于选择缓冲区大小的线程和页面(甚至是关于 SO 的一些)。一些人建议尝试选择 native 文件系统使用的一个,以尽量减少对部分块等进行读取操作的机会。比如4100字节的buffer,NTFS默认是4096,那么多出来的4bits就需要单独读操作,非常浪费。

所以坚持使用 2、1024、2048、4096、8192 等的幂。我看到一些推荐的缓冲区大小为 32KB,而其他人建议将缓冲区设置为输入文件的大小(对于小文件可能没问题) ,但是大文件呢?)。

坚持使用原生 block 大小的缓冲区有多重要?现代地说(假设现代 SATA 驱动器或更好,至少有 8Mb 的驱动器缓存,以及其他现代操作系统“魔法”来优化 I/O)缓冲区大小有多重要,我应该如何最好地确定将我的大小设置为多少?我可以静态设置它,还是动态确定它?感谢您的任何见解。

最佳答案

回答你的直接问题:(1) 文件系统倾向于使用 2 的幂,所以你想做同样的事情。 (2) 您的工作缓冲区越大,任何大小不当的影响就越小。

如您所说,如果分配 4100 而实际 block 大小为 4096,则需要两次读取才能填充缓冲区。相反,如果您有一个 1,000,000 字节的缓冲区,那么高或低一个 block 并不重要(因为需要 245 个 4096 字节的 block 来填充该缓冲区)。此外,更大的缓冲区意味着操作系统有更好的机会对读取进行排序。

也就是说,我不会为此使用 NIO。相反,我会使用一个简单的 BufferedInputStream,我的 read() 可能有一个 1k 缓冲区。

NIO 的主要好处是让数据远离 Java 堆。例如,如果您正在读取和写入文件,使用 InputStream 意味着操作系统将数据读入 JVM 管理的缓冲区,JVM 将其复制到堆上缓冲区,然后复制它再次进入堆外缓冲区,然后操作系统读取该堆外缓冲区以写入实际的磁盘 block (通常会添加自己的缓冲区)。在这种情况下,NIO 将消除该 native 堆副本。

但是,要计算散列,您需要在 Java 堆中拥有数据,并且 Mac SPI will move it there .因此,您无法获得 NBI 将数据保存在堆外的好处,并且在 IMO 中,“旧 IO”更易于编写。

只是不要忘记 InputStream.read() 不能保证读取您请求的所有字节。

关于java - 确定合适的缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16067199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com