背景
假设我有一个直接的ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
并假设我将缓冲区传递给AsynchronousSocketChannel以从该套接字读取数据块,一次最多X个字节(此处示例中为1024)。
将套接字转移到直接 ByteBuffer的转移时间非常棒,因为它全部发生在本机OS内存空间中;我还没有通过JVM“血脑”屏障......
问题
假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么最快的方式对我来说是做什么的?
我最初问过“ ...利用sun.misc.Unsafe ”,但也许这是错误的假设。
可能的方法
我目前看到三种方法,我最感兴趣的是#3:
我确实认为,假设 copyMemory 操作完全正如它所宣传的那样,即使在更优化的操作系统空间中,上面的#2方法可能仍然是最优化的,因为我是在开始处理缓冲区之前不要创建缓冲区的重复项。
这与“can I use Unsafe to iterate over a byte[] faster?”问题不同,因为如果没有必要,我甚至不打算在内部将字节拉入byte []。
感谢您的时间;只是好奇,如果有人(彼得?)已经疯了,不安全做这样的事情。
答案 0 :(得分:1)
ByteBuffer
方法非常快,因为这些方法是内在函数,VM已将它们映射到非常低级别的指令。比较这两种方法:
byte[] bytes = new byte[N];
for(int m=0; m<M; m++)
for(int i=0; i<bytes.length; i++)
sum += bytes[i];
ByteBuffer bb = ByteBuffer.allocateDirect(N);
for(int m=0; m<M; m++)
for(int i=0; i<bb.remaining(); i++)
sum += bb.get(i);
在我的机器上,差异是0.67ns vs 0.81ns(每个循环)。
我有点惊讶ByteBuffer没有byte []那么快。但我认为你绝对不应该将它复制到byte []然后访问。