有效地发送大量INT []在Java中的插座 [英] Efficiently send large int[] over sockets in Java

查看:111
本文介绍了有效地发送大量INT []在Java中的插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个Java应用程序,我需要尽快送50万整数数组从一个Android手机到另一个Android手机,通过套接字连接成为可能。的主要瓶颈似乎被转换的整数,以便插座可以采取它们,我是否使用ObjectOutputStreams,的ByteBuffers,或低级掩模和移位转换。什么是发送一个int []通过套接字从一个Java应用到另一个最快的方法是什么?

I am working on a Java application where I need to send an array of 500,000 integers from one Android phone to another Android phone over a socket connection as quickly as possible. The main bottleneck seems to be converting the integers so the socket can take them, whether I use ObjectOutputStreams, ByteBuffers, or a low level mask-and-shift conversion. What is the fastest way to send an int[] over a socket from one Java app to another?

下面是code的一切我试过到目前为止,与上LG的Optimus V基准我测试的(600 MHz的ARM处理器,Android 2.2的)。

Here is the code for everything I've tried so far, with benchmarks on the LG Optimus V I'm testing on (600 MHz ARM processor, 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;
}

使用的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;
}

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

最后,code我用来发送字节[]:在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();
}

我在写一篇插槽两侧的code,所以我可以尝试任何一种字节序的,COM pression,系列化等我们有了一种方式更有效地完成这一转换中Java语言。请帮帮忙!

I'm writing the code on both sides of the socket so I can try any kind of endianness, compression, serialization, etc. There's got to be a way to do this conversion more efficiently in Java. Please help!

推荐答案

正如我在评论说,我觉得你对撞你的处理器的极限。由于这可能是帮助他人,我会打破它。这是你的循环整数转换为字节:

As I noted in a comment, I think you're banging against the limits of your processor. As this might be helpful to others, I'll break it down. Here's your loop to convert integers to bytes:

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

此循环将执行50万次。你600MHz的处理器每秒可以处理大约6亿的操作。因此循环的每次迭代将消耗大约的第二1/1200每个操作

This loop executes 500,000 times. You 600Mhz processor can process roughly 600,000,000 operations per second. So each iteration of the loop will consume roughly 1/1200 of a second for every operation.

再次使用非常粗略的数据(我不知道ARM指令集,因此可能会有更多或更少的每个动作),这里有一个操作数:

Again, using very rough numbers (I don't know the ARM instruction set, so there may be more or less per action), here's an operation count:

  • 测试/分支:5(柜台检索,检索数组的长度,比较,分支,增加计数器)
  • 面膜和转变:10×4(柜台检索,检索输入数组的基础上,新增,恢复面具,和,移位,乘法计数器,加偏移量,增加输出基地,专卖店)

确定,所以在粗糙的数字,这个循环需要的充其量的一千二百分之五十五秒或0.04秒。但是,你不处理最好的情况下。一方面,与数组这个大你不打算从处理器高速缓存中受益,所以你会引入等待状态到每一个阵列存储和加载。

OK, so in rough numbers, this loop takes at best 55/1200 of a second, or 0.04 seconds. However, you're not dealing with best case scenario. For one thing, with an array this large you're not going to benefit from a processor cache, so you'll introduce wait states into every array store and load.

另外,我描述可以或可以不直接转化成机器code中的基本操作。如果不是(我不怀疑),循环将耗资超过我所描述的。

Plus, the basic operations that I described may or may not translate directly into machine code. If not (and I suspect not), the loop will cost more than I've described.

最后,如果你真的不走运,在JVM还没有JIT-ED的code,因此对于循环的某些部分(或全部)这是除preting字节code,而不是执行原生指令。我不知道有足够的了解的Dalvik他有什么看法。

Finally, if you're really unlucky, the JVM hasn't JIT-ed your code, so for some portion (or all) of the loop it's interpreting bytecode rather than executing native instructions. I don't know enough about Dalvik to comment on that.

这篇关于有效地发送大量INT []在Java中的插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆