2011-01-11 71 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重組,可能會有所幫助。根據您的應用程序,您可能可以在需要它們之前請求項目,或使用緩存來創建更好的用戶存在,但我們需要了解更多信息才能給您提供有意義的建議。