5

What is the fastest way to fill up a pre-allocated ByteBuffer in Java?

I first set the size of the byte buffer with allocateDirect(), this only needs to be done once. After, I need to fill it up continuously (recycling it) as fast as possible with new data which arrives as a byte[] array, around every 5ms, and without eating memory as I have already pre-allocated the byte buffer. At the moment, I use the put() instruction, which in my system takes around 100ms to complete. Is there another way to fill up the byte buffer? Does thewrap() function run faster without re-allocating the array?

1

2 Answers 2

8

I would hope you mean byte[] not Byte[]

A put() is the fastest way to copy a byte[] into a ByteBuffer. An even faster way is to write into the ByteBuffer in the first place and not use a byte[] at all.

If the copy is taking 100ms, perhaps you are copying too much data. In this test it copies 1 MB in 128 micro-seconds.

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); 

prints

Average time to copy 1 MB was 128.9 us 
Sign up to request clarification or add additional context in comments.

6 Comments

Oops, yes I meant byte[]. So the only way to fill up continuously the ByteBuffer, the fastest way possible, is by using ".put(...)"? The data I must fill up in every cycle, is as in your test, around 1MB, which I cannot get around or reduce.
Are you sure its 100 ms and not 100 micro-seconds? If you cannot reduce it the best solution is to not use a byte[] at all and have what ever produces this write directly to the ByteBuffer.
yes it takes around 100ms. Unfortunately the data I get from the hardware callback arrives as a byte[] array, and the final instruction that needs to process it, only accepts a ByteBuffer, which also I can't change. So I must find the fastest possible way to copy this data across, and without re-allocating memory all the time.
Can you run my test because there is no way that a put() on 1 MB should be taking 100 ms? It should be closer to 0.1 ms.
The answer is good and I like that you provide a testcode for the speed of ByteBuffer.put() .... But actually it does not provide any information on the speed of ByteBuffer.wrap()... You say put() is the fastest way, but actually you need to take into account the creation of the ByteBuffer object also... ByteBuffer.wrap() copies the bytes and instantiates a ByteBuffer at the same time.. Are you sure this is slower than instantiating a ByteBuffer and then using put() to copy the bytes? Or do you normally just use one ByteBuffer Object for several byte copy tasks?
|
2

wrap should be much faster, as --if I understand the doc correctly-- it does not copy the byte array, but just sets the member variables (capacity/limit/position). wrap only makes sense, if you already got the byte[] with the desired data from somewhere, of course.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.