Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android HttpClient performance

I developing android app which uses a lot of http requests to web service. At first, I was creating a new HttpClient instance before every request. To increase performance I try to do requests in many threads. So, I created single HttpClient instance, shared by all threads, using 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);

But performance decreased, to my surprise. I have measured time, to be spended to exequte requests in such way:

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

Here this is a log, which I get with simple DefaultHttpClient without parameters new instance per request:

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

And what I get with ThreadSafeClientConnManager and single HttpClient instance:

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

What happens and how can I fight this?

UPDATE

Use keep-alive advantage - is what I want. But when I create new HttpClient instance for every request connection can not be reused. Despite of this, such version runs faster, reasons of it is unclear for me.

like image 950
Ilya Izhovkin Avatar asked Jan 11 '11 05:01

Ilya Izhovkin


1 Answers

It is all very simple. HttpClient per default allows only two concurrent connections to the same target host as required by the HTTP specification. So, effectively your worker threads spend most of their execution time blocked waiting for those two connections to become available.

You should increase the 'max connections per route' limit to reduce / eliminate worker thread contention.

You might also want to check out the benchmark used by Apache HttpComponents project to measure performance of HttpClient.

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

like image 144
ok2c Avatar answered Oct 21 '22 05:10

ok2c