2011-01-11 5 views
9

Je développe l'application Android qui utilise beaucoup de demandes http au service Web. Au début, je créais une nouvelle instance de HttpClient avant chaque requête. Pour augmenter les performances, j'essaie de faire des requêtes dans de nombreux threads. Donc, j'ai créé seule instance HttpClient, partagée par toutes les discussions, en utilisant ThreadSafeConnectionManager:Android HttpClient performance

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

Mais une baisse des performances, à ma grande surprise. J'ai mesuré le temps, être spended à exequte demandes de telle manière:

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

Voici c'est un journal, que je reçois avec DefaultHttpClient simple, sans paramètres nouvelle instance par requête:

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 

Et ce Je reçois avec ThreadSafeClientConnManager et unique instance 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 

Que se passe et comment puis-je lutter contre cela?

MISE À JOUR

Utiliser avantage keep-alive - est ce que je veux. Mais lorsque je crée une nouvelle instance HttpClient pour chaque requête, la connexion ne peut pas être réutilisée. Malgré cela, une telle version fonctionne plus vite, les raisons de cela ne sont pas claires pour moi.

+0

Tout ce que je peux dire est que parallèle avec la synchronisation est plus lent que série sans synchronisation. C'est pourquoi les ports Parallel sont morts et les ports USB Serial ont gagné. –

+1

Toutes les demandes sont-elles adressées au même service Web/hôte? Il se peut que ce soit le serveur qui ne l'aime pas, ou que vous perdiez votre avantage HTTP 'keepalive' en faisant 10 unités de travail sur 100 threads. Les demandes sont-elles grandes? La bande passante pourrait être un goulot d'étranglement. –

+0

Oui, les demandes concernent le même service Web. Le nombre de threads est inférieur au nombre de requêtes, en fait je le teste avec 2 ou 3 threads. Les demandes sont petites, peu de tags xml. –

Répondre

15

Tout est très simple. HttpClient par défaut autorise uniquement deux connexions simultanées au même hôte cible, comme requis par la spécification HTTP. Ainsi, vos threads de travail passent la plupart de leur temps d'exécution à attendre que ces deux connexions deviennent disponibles.

Vous devez augmenter la limite "connexions maximales par route" pour réduire/éliminer les conflits de threads de travail.

Vous pouvez également consulter le cas-test utilisé par le projet Apache HttpComponents pour mesurer les performances de HttpClient.

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

+0

Cela semble être ce dont j'ai besoin, merci! –

0

Je soupçonne que la commutation de contexte entraîne des performances médiocres avec le gestionnaire thread-safe, et vous devriez arrêter de l'utiliser. Je suppose que vous pouvez comparer le client Apache avec le client Java par défaut, mais je ne pense pas que vous obtiendrez beaucoup de gain de performance.

Personnellement, j'ai trouvé l'analyseur XML DOM un peu lent, donc si vous utilisez le reformatage XML, cela peut aider. En fonction de votre application, vous pourrez peut-être demander des articles avant d'en avoir besoin ou utiliser la mise en cache pour créer une meilleure expérience utilisateur, mais nous aurions besoin d'en savoir plus pour vous donner des conseils utiles.