Jer*_*ers 14 java sockets performance android casting
我正在开发一个Java应用程序,我需要尽快通过套接字连接从一部Android手机向另一部Android手机发送500,000个整数数组.主要的瓶颈似乎是转换整数,因此套接字可以使用它们,无论我使用ObjectOutputStreams,ByteBuffers还是低级掩码和移位转换.通过套接字将int []从一个Java应用程序发送到另一个Java应用程序的最快方法是什么?
这是迄今为止我尝试过的所有内容的代码,LG Optimus V上的基准测试我正在测试(600 MHz ARM处理器,Android 2.2).
低级掩码和移位:0.2秒
public static byte[] intToByte(int[] input)
{
byte[] output = new byte[input.length*4];
for(int i = 0; i < input.length; i++) {
output[i*4] = (byte)(input[i] & 0xFF);
output[i*4 + 1] = (byte)((input[i] & 0xFF00) >>> 8);
output[i*4 + 2] = (byte)((input[i] & 0xFF0000) >>> 16);
output[i*4 + 3] = (byte)((input[i] & 0xFF000000) >>> 24);
}
return output;
}
Run Code Online (Sandbox Code Playgroud)
使用ByteBuffer和IntBuffer:0.75秒
public static byte[] intToByte(int[] input)
{
ByteBuffer byteBuffer = ByteBuffer.allocate(input.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(input);
byte[] array = byteBuffer.array();
return array;
}
Run Code Online (Sandbox Code Playgroud)
ObjectOutputStream:3.1秒(我尝试使用DataOutPutStream和writeInt()而不是writeObject()来改变它,但它并没有太大区别)
public static void sendSerialDataTCP(String address, int[] array) throws IOException
{
Socket senderSocket = new Socket(address, 4446);
OutputStream os = senderSocket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream (os);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(array);
oos.flush();
bos.flush();
os.flush();
oos.close();
os.close();
bos.close();
senderSocket.close();
}
Run Code Online (Sandbox Code Playgroud)
最后,我用来发送byte []的代码比intToByte()函数增加了0.2秒
public static void sendDataTCP(String address, byte[] data) throws IOException
{
Socket senderSocket = new Socket(address, 4446);
OutputStream os = senderSocket.getOutputStream();
os.write(data, 0, data.length);
os.flush();
senderSocket.close();
}
Run Code Online (Sandbox Code Playgroud)
我在套接字的两边编写代码,所以我可以尝试任何类型的字节序,压缩,序列化等.必须有一种方法在Java中更有效地进行这种转换.请帮忙!
正如我在评论中指出的那样,我认为你正在抨击处理器的极限.由于这可能对其他人有所帮助,我会将其分解.这是将整数转换为字节的循环:
for(int i = 0; i < input.length; i++) {
output[i*4] = (byte)(input[i] & 0xFF);
output[i*4 + 1] = (byte)((input[i] & 0xFF00) >>> 8);
output[i*4 + 2] = (byte)((input[i] & 0xFF0000) >>> 16);
output[i*4 + 3] = (byte)((input[i] & 0xFF000000) >>> 24);
}
Run Code Online (Sandbox Code Playgroud)
该循环执行500,000次.600Mhz处理器每秒可处理大约600,000,000次操作.因此,对于每个操作,循环的每次迭代将消耗大约1/1200秒.
再次,使用非常粗略的数字(我不知道ARM指令集,因此每个操作可能有更多或更少),这是一个操作计数:
好的,所以在粗略的数字中,这个循环最多需要55/1200秒,或0.04秒.但是,您没有处理最佳案例场景.首先,对于这么大的数组,您不会从处理器缓存中受益,因此您将在每个数组存储和加载中引入等待状态.
另外,我描述的基本操作可能会或可能不会直接转换为机器代码.如果不是(我怀疑没有),那么循环的成本将超过我所描述的.
最后,如果你真的不走运,JVM还没有JIT编写你的代码,所以对于循环的某些部分(或全部)它解释字节码而不是执行本机指令.我不太了解达尔维克对此发表评论.