相关疑难解决方法(0)

ByteBuffer.allocate()与ByteBuffer.allocateDirect()

allocate()或者allocateDirect(),这是一个问题.

多年以来我一直坚持认为,因为DirectByteBuffers是OS级别的直接内存映射,所以get/put调用的执行速度比HeapByteBuffers 快.到目前为止,我从未真正有兴趣了解有关情况的具体细节.我想知道两种类型的ByteBuffer哪种更快,哪种条件更快.

java performance nio bytebuffer

135
推荐指数
4
解决办法
7万
查看次数

何时使用Array,Buffer或direct Buffer

在编写用于OpenGL库的Matrix类时,我遇到了是否使用Java数组或缓冲区策略来存储数据的问题(JOGL为Matrix操作提供了直接缓冲区复制).为了分析这一点,我编写了一个小型性能测试程序,它比较了Arrays与Buffers vs direct Buffers的循环和批量操作的相对速度.

我想在这里与你分享我的成果(因为我觉得它们很有趣).请随时评论和/或指出任何错误.
可以在pastebin.com/is7UaiMV上查看代码.

笔记

  • 循环读取数组实现为A [i] = B [i],否则JIT优化器将完全删除该代码.实际var = A [i]似乎几乎相同.

  • 在数组大小为10,000的示例结果中,JIT优化器很可能已使用类似System.arraycopy的实现替换了循环数组访问.

  • 没有批量获取缓冲区 - >缓冲区,因为Java将A.get(B)实现B.put(A),因此结果与批量放置结果相同.

结论

在几乎所有情况下,强烈建议使用Java内部数组.不仅提高/获取速度大大加快,JIT还能够对最终代码执行更好的优化.

只有在以下两种情况适用时才应使用缓冲区:

  • 您需要处理大量数据.
  • 该数据大部分或总是经过批量处理.

请注意,后备缓冲区具有Java数组,用于补偿缓冲区的内容.建议在此后​​台缓冲区上执行操作,而不是循环put/get.

只有在担心内存使用情况且永远不会访问基础数据时,应使用直接缓冲区.它们比非直接缓冲区稍慢,如果访问基础数据则要慢得多,但使用的内存较少.此外,在使用直接缓冲区时,将非字节数据(如float-arrays)转换为字节时会产生额外的开销.

有关详细信息,请参阅此处

样本结果

注意:百分比仅为便于阅读而没有实际意义.

使用大小为16且10,000,000次迭代的数组...

-- Array tests: -----------------------------------------

Loop-write array:           87.29 ms  11,52%
Arrays.fill:                64.51 ms   8,51%
Loop-read array:            42.11 ms   5,56%
System.arraycopy:           47.25 ms   6,23%

-- …
Run Code Online (Sandbox Code Playgroud)

java arrays performance buffer

22
推荐指数
2
解决办法
1万
查看次数

标签 统计

java ×2

performance ×2

arrays ×1

buffer ×1

bytebuffer ×1

nio ×1