Java ByteBuffer 放置与包装
Posted
技术标签:
【中文标题】Java ByteBuffer 放置与包装【英文标题】:Java ByteBuffer put vs wrap 【发布时间】:2012-06-19 08:26:51 【问题描述】:用 Java 填充预先分配的 ByteBuffer
的最快方法是什么?
我首先用allocateDirect()
设置字节缓冲区的大小,这只需要做一次。之后,我需要以byte[]
数组的形式尽可能快地连续填充它(回收它),大约每 5ms 一次,并且不占用内存,因为我已经预先分配了字节缓冲区。
目前,我使用put()
指令,在我的系统中完成该指令大约需要 100 毫秒。
是否有另一种方法来填充字节缓冲区? wrap()
函数在不重新分配数组的情况下运行得更快吗?
【问题讨论】:
你可以试试 System.arraycopy。检查:Is it better to use System.arraycopy(…) than a for loop for copying arrays? 【参考方案1】:我希望你的意思是 byte[]
而不是 Byte[]
put()
是将 byte[] 复制到 ByteBuffer 的最快方法。一种更快的方法是首先写入ByteBuffer
,而根本不使用byte[]
。
如果复制需要 100 毫秒,则可能是您复制了太多数据。在此测试中,它会在 128 微秒内复制 1 MB。
ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024);
byte[] bytes = new byte[bb.capacity()];
int runs = 50000;
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
bb.clear();
bb.put(bytes);
long time = System.nanoTime() - start;
System.out.printf("Average time to copy 1 MB was %.1f us%n", time / runs / 1e3);
打印
Average time to copy 1 MB was 128.9 us
【讨论】:
糟糕,我的意思是字节 []。因此,持续填充 ByteBuffer 的唯一方法(可能是最快的方法)是使用“.put(...)”?我必须在每个周期中填写的数据,就像你的测试一样,大约 1MB,我无法绕过或减少。 你确定它是 100 毫秒而不是 100 微秒吗?如果你不能减少它,最好的解决方案是根本不使用 byte[] 并将产生这种写入的东西直接写入 ByteBuffer。 是的,大约需要 100 毫秒。不幸的是,我从硬件回调中获得的数据以 byte[] 数组的形式到达,需要处理它的最终指令只接受一个 ByteBuffer,我也无法更改。所以我必须找到最快的方法来复制这些数据,而不是一直重新分配内存。 您能否运行我的测试,因为 1 MB 上的 put() 不可能花费 100 毫秒?它应该更接近 0.1 毫秒。 答案很好,我喜欢你提供 ByteBuffer.put() 速度的测试代码.. 但实际上它没有提供任何关于ByteBuffer.wrap()
.. 速度的信息.你说put()
是最快的方法,但实际上你还需要考虑ByteBuffer对象的创建...ByteBuffer.wrap()
复制字节并同时实例化一个ByteBuffer..你确定这是比实例化 ByteBuffer 然后使用 put()
复制字节慢?还是你通常只使用一个 ByteBuffer 对象来完成多个字节复制任务?【参考方案2】:
wrap 应该更快,因为——如果我正确理解了文档——它不会复制字节数组,而只是设置成员变量(容量/限制/位置)。 当然,如果您已经从某个地方获得了带有所需数据的 byte[],那么 wrap 才有意义。
【讨论】:
以上是关于Java ByteBuffer 放置与包装的主要内容,如果未能解决你的问题,请参考以下文章
java中怎么在客户端与服务器之间以bytes(ByteBuffer)的方式拷贝二进制文件?