2013-04-12 215 views
0

我正在研究一个Android应用程序,需要与服务器(在我的电脑上运行)进行通信,这也是我写的。 问题是InputStream.read()需要一个永恒,处理200kb大约需要30秒。也许垃圾收集涉及某种方式,在我的循环过程中,它不时被调用,但列出的延迟只有2或3毫秒,总共可能是20毫秒,所以我不认为这是问题所在。Android InputStream.read()极其缓慢

我的代码:

client = new Socket("192.168.1.1", 1235); 
client.setTcpNoDelay(true); 
client.setReceiveBufferSize(1048576); 
InputStream is = client.getInputStream(); 

byte[] buffer = new byte[1048576]; 
int i = 0; 
int length = -1; 

while (true) 
{ 
    int b = is.read(); 
    if (b == -1) 
    { 
     success = false; 
     break; 
    } 
    buffer[i] = (byte) b; 

    if (i == length) 
     break; 

    if (i == 3) 
    { 
     length = buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24; 
    } 

    i++; 
} 

我没有真正经历Java和Android中的编程总初学者,所以我不知道为什么它是那该死的缓慢。

+0

建议:如果您想在Android中创建服务器端客户端应用程序,我强烈建议您检查一下将为您进行通信的[middleware](http://en.wikipedia.org/wiki/Middleware)例如[Apache Thrift](http://thrift.apache.org/)。 – m0skit0

回答

0

你为什么要单独读取每个字节?它看起来像你真的想读取前3个字节,并找出你的长度,然后读取该块。

IE:

final byte[] lengthBuffer = new byte[3]; 

int b = is.read(lengthBuffer); 

// make sure b was 3 and do your length calculation 

final byte buffer = new byte[length]; 

b = is.read(buffer); 

// check b and then you have your bytes 

那么你至少可以拿到的InputStream可以提供一次读取数据块,而不是一个字节的优化。而且你没有像现在那样分配这个巨型数组。

+0

好吧,这是更快,更快,甚至太快:/ 现在它完成之前所有的数据有... 顺便说一句:我明白,做200k迭代没有像优化的东西一样快,但30秒是有趣的是,这应该仍然只需要几毫秒,.read()必须非常低效地执行。 – Hidden

+0

好吧,我只是循环读取直到达到长度,比读取每个字节还要快上千倍 – Hidden

+1

@Hidden读取的写入效率不高 - 其访问硬件。通过在流中进行大量小读操作,您可以从硬缓存中进行大量小读操作。这需要时间 - 你不再以时钟速度运行,你受到总线时间和延迟的限制。在做网络,存储等任何事情时,你必须意识到最终你遇到了物理组件,并且需要写下它们的工作方式。 –

0

您一次只读1个字节。这是非常低效的。你想尽可能多地读取大量的字节。这就是你的应用速度缓慢的原因。