2011-01-11 74 views
9

我开发的Android应用程序使用了很多http请求到Web服务。起初,我在每次请求之前都创建了一个新的HttpClient实例。 为了提高性能,我尝试在很多线程中做请求。所以,我创建一个HttpClient的实例,所有线程共享,使用ThreadSafeConnectionManager:Android HttpClient性能

SchemeRegistry registry = new SchemeRegistry(); 
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 

BasicHttpParams params = new BasicHttpParams(); 
ConnManagerParams.setMaxTotalConnections(params, 100); 
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
HttpProtocolParams.setUseExpectContinue(params, true); 

ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params, registry); 
HttpClient client = new DefaultHttpClient(connManager, params); 

但性能下降,出乎我的意料。我有分寸的时间,待spended到exequte以这样的方式请求:

long startTime = System.currentTimeMillis(); 
HttpResponse response = client.execute(postRequest); 
long reqTime = System.currentTimeMillis() - startTime; 
Log.i("SyncTimer", "Request time:" + reqTime); 

这里,这是一个记录,我用简单的DefaultHttpClient获得不带参数的每个请求的新实例:

01-11 11:10:51.136: INFO/SyncTimer(18400): Request time:1076 
01-11 11:10:54.686: INFO/SyncTimer(18400): Request time:1051 
01-11 11:10:57.996: INFO/SyncTimer(18400): Request time:1054 
01-11 11:10:59.166: INFO/SyncTimer(18400): Request time:1070 
01-11 11:11:00.346: INFO/SyncTimer(18400): Request time:1172 
01-11 11:11:02.656: INFO/SyncTimer(18400): Request time:1043 

什么我得到ThreadSafeClientConnManager和单HttpClient的实例:

01-11 11:06:06.926: INFO/SyncTimer(18267): Request time:7001 
01-11 11:06:10.412: INFO/SyncTimer(18267): Request time:3385 
01-11 11:06:20.222: INFO/SyncTimer(18267): Request time:9801 
01-11 11:06:23.622: INFO/SyncTimer(18267): Request time:2058 
01-11 11:06:29.906: INFO/SyncTimer(18267): Request time:6268 
01-11 11:06:34.746: INFO/SyncTimer(18267): Request time:3525 
01-11 11:06:50.302: INFO/SyncTimer(18267): Request time:15551 

什么发生,我该怎么打呢?

UPDATE

使用保活的优势 - 就是我想要的。但是当我为每个请求连接创建新的HttpClient实例时,无法重用。尽管如此,这样的版本运行速度更快,原因目前还不清楚。

+0

我可以说是同步平行比串行同步不慢。因此,为什么并行端口死亡和串行USB端口赢了。 – 2011-01-11 05:45:12

+1

所有的请求都是同一个web服务/主机吗?它可能是不喜欢它的服务器,或者你可能会通过在100个线程上执行10个单元工作而失去HTTP'keepalive'优势。请求大吗?带宽可能是一个瓶颈。 – 2011-01-11 06:32:50

回答

15

这一切都很简单。默认情况下,HttpClient只允许两个并发连接到HTTP规范所要求的同一目标主机。因此,实际上,您的工作线程会阻止大部分执行时间,等待这两个连接变为可用。

您应该增加“每条路由的最大连接数”限制以减少/消除工作线程争用。

您可能还想查看Apache HttpComponents项目使用的基准来衡量HttpClient的性能。

http://wiki.apache.org/HttpComponents/HttpClient3vsHttpClient4vsHttpCore

0

我怀疑上下文切换会导致线程安全管理器的糟糕表现,您应该停止使用它。我想你可以将Apache客户端与默认的Java客户端进行比较,但我认为你不会获得很大的性能提升。

就我个人而言,我发现DOM XML解析器有点慢,所以如果您使用XML重组,可能会有所帮助。根据您的应用程序,您可能可以在需要它们之前请求项目,或使用缓存来创建更好的用户存在,但我们需要了解更多信息才能给您提供有意义的建议。