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