Fastest byte array concatenation method

I got a map containing n message parts as a byte array. After the last fragment found its way on the map, the message should be concatenated. I found two solutions that should meet the requirements. The first uses System.arraycopy:

public byte[] getMessageBytes() throws IOException {
    byte[] bytes = new byte[0];
    for (final Map.Entry<Short,byte[]> entry : myMap.entrySet()) {
        byte[] entryBytes = entry.getValue();
        byte[] temp = new byte[bytes.length + entryBytes.length];
        System.arraycopy(bytes, 0, temp, 0, bytes.length);
        System.arraycopy(entryBytes, 0, temp, bytes.length, entryBytes.length);
        bytes = temp;
    }
    return bytes;
}

And the second uses ByteArrayOutputStream:

public byte[] getMessageBytes() throws IOException {
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (final Map.Entry<Short,byte[]> entry : myMap.entrySet()) {
        baos.write(entry.getValue());
    }
    baos.flush();
    return baos.toByteArray();
}

What is the best method that can be seen from the angle of performance and memory usage? Is there an alternative way to perform concatenation that is even better?

+3
source share
5 answers

Since you can find out the message size by adding the lengths of the parts, I would:

  • add the length of the fragments and select the output array;
  • arraycopy() .

, , . .

+8

, ( )

public byte[] getMessageBytes() throws IOException {
    long amount = 0L;
    long offset = 0L;
    // no reason to use entrySet() if you just use the values
    for (byte[] arr : myMap.values()) {
        amount += arr.length;
    }
    byte[] dest = new byte[amount];
    for (byte[] arr : myMap.values()) {
        System.arraycopy(arr, 0, dest, offset, arr.length);
        offset += arr.length;
    }
    return dest;
}

( aix's)

+4

- .

SortedMap, TreeMap, ?

0

, , - O (n ^ 2), , . .

ByteArrayOutputStream : O (n), .

, : , System.arraycopy. , ByteArrayOutputStream .

0

.

InputStream , , , . SequenceInputStream, ByteArrayInputStreams. :

Collection<byte[]> values = map.values();
List<ByteArrayInputStream> streams = new ArrayList<ByteArrayInputStream>(values.size());
for (byte[] bytes : values) {
    streams.add(new ByteArrayInputStream(bytes));
}
return new SequenceInputStream(Collections.enumeration(streams));
0

All Articles