how to convert short array to byte array
Solution 1:
I found ByteBuffer to be the slowest conversion method out of three that I've profiled. See below...
Platform: Nexus S, Android 4.1.1, No SIM card
Method #1: Use a ByteBuffer
byte [] ShortToByte_ByteBuffer_Method(short [] input)
{
int index;
int iterations = input.length;
ByteBuffer bb = ByteBuffer.allocate(input.length * 2);
for(index = 0; index != iterations; ++index)
{
bb.putShort(input[index]);
}
return bb.array();
}
Method #2: Twiddle bits directly
byte [] ShortToByte_Twiddle_Method(short [] input)
{
int short_index, byte_index;
int iterations = input.length;
byte [] buffer = new byte[input.length * 2];
short_index = byte_index = 0;
for(/*NOP*/; short_index != iterations; /*NOP*/)
{
buffer[byte_index] = (byte) (input[short_index] & 0x00FF);
buffer[byte_index + 1] = (byte) ((input[short_index] & 0xFF00) >> 8);
++short_index; byte_index += 2;
}
return buffer;
}
Method #3: Use C via JNI
TypeCast.java
package mynamespace.util;
public class TypeCast
{
public static native byte [] shortToByte(short [] input);
static
{
System.loadLibrary("type_conversion");
}
}
native.c
#include <jni.h>
#include <string.h>
jbyteArray Java_mynamespace_util_TypeCast_shortToByte(JNIEnv *env, jobject obj, jshortArray input)
{
jshort *input_array_elements;
int input_length;
jbyte *output_array_elements;
jbyteArray output;
input_array_elements = (*env)->GetShortArrayElements(env, input, 0);
input_length = (*env)->GetArrayLength(env, input);
output = (jbyteArray) ((*env)->NewByteArray(env, input_length * 2));
output_array_elements = (*env)->GetByteArrayElements(env, output, 0);
memcpy(output_array_elements, input_array_elements, input_length * 2);
(*env)->ReleaseShortArrayElements(env, input, input_array_elements, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, output, output_array_elements, 0);
return output;
}
Results:
For a one million element input array, the time of execution is as follows:
Method #1 ByteBuffer: 865 ms
Method #2 Twiddle: 299 ms
Method #3 C: 39 ms
Solution 2:
Java short
is a 16-bit type, and byte
is an 8-bit type. You have a loop that tries to insert N
shorts into a buffer that's N
-bytes long; it needs to be 2*N
bytes long to fit all your data.
ByteBuffer byteBuf = ByteBuffer.allocate(2*N);
while (N >= i) {
byteBuf.putShort(buffer[i]);
i++;
}