Java 使用sun.misc.Unsafe,从直接字节缓冲区扫描字节的最快方法是什么?

Java 使用sun.misc.Unsafe,从直接字节缓冲区扫描字节的最快方法是什么?,java,performance,unsafe,bytebuffer,Java,Performance,Unsafe,Bytebuffer,背景 假设我有一个直接的ByteBuffer: ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 假设我将缓冲区传递给一个接口,以便一次最多读取X字节(本例中为1024字节)的套接字数据块 从套接字到直接字节缓冲区的传输时间非常美妙,因为它都发生在本机操作系统内存空间中;我还没有通过JVM的“血脑”屏障 问题 假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么最快的方法是什么 我最初问的是“利用”,但这可能是错误的假设 可

背景

假设我有一个直接的ByteBuffer:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
假设我将缓冲区传递给一个接口,以便一次最多读取X字节(本例中为1024字节)的套接字数据块

从套接字到直接字节缓冲区的传输时间非常美妙,因为它都发生在本机操作系统内存空间中;我还没有通过JVM的“血脑”屏障

问题

假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么最快的方法是什么

我最初问的是“利用”,但这可能是错误的假设

可能的方法

我目前看到三种方法,我最好奇的是#3:

  • (默认)使用ByteBuffer将字节直接从本机操作系统空间拉入内部字节[1024]构造
  • (不安全)使用不安全的ops直接从ByteBuffer中提取值,跳过ByteBuffer标准get ops的所有边界检查。Peter Lawrey的回答似乎表明,JIT编译器(“intrinsic”)甚至可以将不安全中的原始本机方法优化为单机指令,从而获得更出色的访问时间。(===更新===有趣的是,底层DirectByteBuffer类似乎正是针对感兴趣的人使用的。)
  • (香蕉)以某种反人类罪的方式,使用不安全的方法,我可以将ByteBuffer的字节[1024]直接指向VM内部存在的相同内存地址,然后使用标准的int索引开始访问数组吗?(这就假设“copyMemory”操作可能会在操作系统级别上完成一些非常优化的工作
  • 我确实想到,即使在更优化的操作系统空间中,假设copyMemory操作完全按照它所宣传的做,那么上面的#2方法可能仍然是最优化的方法,因为我在开始处理之前没有创建缓冲区的副本

    这与“”问题不同,因为如果没有必要,我甚至不打算在内部将字节拉入字节[]


    感谢您的时间;我很好奇是否有人(Peter?)因为不安全而疯狂地这样做。

    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);
    
    byte[]bytes=新字节[N];
    
    对于(int m=0;mDidn)而言,我不知道ByteBuffer方法的“内在”属性;您是指DirectBuffer类上的“本机”方法吗?在这种情况下,这正是#2在我上面的文章中所做的,因此这是一个好消息。@riyadCalla innal!=native。内在方法是“硬编码”的在JVM中。@assylas我理解;我(错误地)指的是DirectByteBuffer impl类()上的“本机”方法但现在我看了一下,我发现没有“本机”方法,它只是利用不安全来执行这些操作。我错了,谢谢你的捕获。它是不安全的,被视为内在的,而不是ByteBuffer et.al。请参见JavaBenchmark挑剔中缓冲区的另一种非常快速的实现:你做了什么吗g有用(比如打印出)sum的值吗?因为否则JIT会优化它。我认为每个循环0.67ns和0.81ns是非常快的,也许真的那么快,但我有点好奇。