背景
假设我有一个直接的 ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
并假设我将缓冲区传递给AsynchronousSocketChannel以一次从该套接字读取数据块,最多 X 字节(此处示例中为 1024)。
从套接字到直接ByteBuffer 的传输时间非常棒,因为它都发生在本机 OS 内存空间中;我还没有通过JVM“血脑”障碍...
问题
假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么最快的方法是什么?
我最初问“ ......利用sun.misc.Unsafe ”但也许这是错误的假设。
可能的方法
我目前看到三种方法,我最好奇的是#3:
- (默认)使用 ByteBuffer 的bulk-get将字节直接从本机 OS 空间提取到内部 byte[1024] 构造中。
- (不安全)使用 Unsafe 的getByte操作将值直接从 ByteBuffer 中提取出来,从而跳过 ByteBuffer 的标准 get 操作的所有边界检查。Peter Lawrey在这里的回答似乎表明 Unsafe 中的那些原始本机方法甚至可以通过 JIT 编译器(“内在”)优化为单个机器指令,从而获得更出色的访问时间。(===UPDATE=== 有趣,看起来底层的DirectByteBuffer类对感兴趣的人使用get/put 操作正是这样做的。)
- (香蕉)以某种反人类犯罪的方式,使用 Unsafe,我可以将直接 ByteBuffer的内存区域复制到我的 byte[1024] 存在于 VM 内部的相同内存地址,然后开始访问数组使用标准的 int 索引?(这假设“copyMemory”操作可能会在操作系统级别做一些非常优化的事情。
我确实想到,假设copyMemory操作完全符合它所宣传的,即使在更优化的操作系统空间中,上面的#2 方法可能仍然是最优化的,因为我没有在开始处理之前创建缓冲区的副本它。
这与“我可以使用 Unsafe 更快地迭代 byte[] 吗? ”问题不同,因为如果没有必要,我什至不打算在内部将字节拉入 byte[]。
感谢您的时间;只是好奇是否有人(彼得?)对 Unsafe 做这样的事情发疯了。