Производительность Android HttpClient - PullRequest
9 голосов
/ 11 января 2011

Я разрабатываю приложение для 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

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

UPDATE

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

Ответы [ 2 ]

15 голосов
/ 11 января 2011

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

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

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

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

0 голосов
/ 11 января 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...