Производительность Android HttpClient

Я разрабатываю приложение для Android, которое использует множество HTTP-запросов к веб-сервису. Сначала я создавал новый экземпляр HttpClient перед каждым запросом. Чтобы повысить производительность, я стараюсь делать запросы во многих потоках. Итак, я создал единый экземпляр HttpClient, общий для всех потоков, используя ThreadSafeConnectionManager:

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

Но, к моему удивлению, производительность снизилась. Я измерил время, которое будет затрачено на выполнение запросов таким образом:

 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 

Что происходит и как я могу бороться с этим?

ОБНОВИТЬ

Используйте преимущество keep-alive – это то, что я хочу. Но когда я создаю новый экземпляр HttpClient для каждого запроса, соединение не может быть повторно использовано. Несмотря на это, такая версия работает быстрее, причины для меня неясны.

Все очень просто. HttpClient по умолчанию допускает только два одновременных подключения к одному и тому же целевому хосту, как того требует спецификация HTTP. Таким образом, эффективно, что ваши рабочие потоки тратят большую часть своего времени на выполнение, блокируются, ожидая, пока эти два соединения станут доступными.

Вы должны увеличить ограничение «максимальных подключений на один маршрут», чтобы уменьшить / устранить конфликт рабочих потоков.

Вы также можете проверить тест, используемый проектом Apache HttpComponents для измерения производительности HttpClient.

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

Я подозреваю, что переключение контекста приводит к низкой производительности с помощью менеджера потоков, и вы должны прекратить его использовать. Я полагаю, вы могли бы сравнить клиент Apache с клиентом Java по умолчанию, но я не думаю, что вы получите большую выгоду от производительности.

Лично я нашел парсер DOM XML немного медленным, поэтому, если вы используете XML-преобразование, это может помочь. В зависимости от вашего приложения вы можете запросить элементы, прежде чем они вам понадобятся, или использовать кеширование для создания лучшего пользовательского опыта, но нам нужно будет узнать больше, чтобы дать вам осмысленный совет.