Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First HTTP POST and GET attempts are always slow - Is this OS related or network?

I have now just started getting my feet wet in HTTP. I've been timing simple HTTP requsts using GET and POST. The web page I have used is a 3 line php check for the correct $_GET[] and $_POST[] then simply echo the character "1". I use POST and GET with the same, single short name/value pair hoping there will be no need for packet fragmentation to muck things up, and all this is done on a thread that is off from the UI thread. The requests are looped on the phone several times while timing them. All works well. (See code below) That is, I get back the response of "1". But there is a persistent timing issue. What I observe is that:

  1. In the first attempt the time to make the request is much longer than the subsequent trys in both the GET and POST methods.

  2. The rest of the attempts are always much faster for both.

  3. GET is always faster than POST.

All these are true for 3G and Wifi connection (but with Wifi much faster overall as expected).

I have tried this with the BasicResponseHandler(), and with the more manual Buffered IO Stream methods with the same results.

I believe I understand 3. as being a result that a POST requires two transmissions, one for the 'HTTP 100' return then the packet body. - Is this correct?

My primary question is what is happening in the first request attempts that are so slow? Sometimes it takes several seconds(!). Is it the network that is holding things up or Android putting it into a socket creating queue of some sort? If it is Android, is there a way to more properly code and avoid this? Is there something about keeping a socket open to make this an issue only once during execution? If so, is it good practice to do so? Admittedly, this apsect I am most clueless about.

I have found some of discussion on this, but none hitting this aspect directly.

--

The basic code for both GET and POST methods looks like this (minus the try/catches), and are performed in a thread off the UI, first the GET method then the POST method: (output below)

GET part of it:

public String[] HTTPGETIt(int numrounds)
{
 HttpClient httpclient = new DefaultHttpClient();
 httpclient.getParams().setParameter (CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
 HttpGet GETRequest = new HttpGet("http://mypage.com/epoch.php?mynameis=tam");
 ResponseHandler <String> MyBRH = new BasicResponseHandler();
 String[] GETResult = new String[numrounds];

 int i = 0;
 long timestart, DT;
 while(i < numrounds)
 {
  timestart = System.currentTimeMillis();
  GETResult[i] = httpclient.execute(GETRequest, MyBRH);
  DT = System.currentTimeMillis() - timestart;
  Log.d(TAG, "(" + i + ") GET-Round Trip was "+ DT + " ms.");
  i++;
 }//while i <= numrounds
 httpclient.getConnectionManager().shutdown();
 return GETResult;
} //END HTTPGETIt

And the POST version:

public String[] HTTPPOSTIt(int numrounds)
{
 String Place = "HTTPPostping";
 HttpClient httpclient = new DefaultHttpClient();
 httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
 HttpPost PostRequest = new HttpPost("http://mypage.com/epoch.php");
 ResponseHandler <String> MyBRH = new BasicResponseHandler();
 String[] POSTResult = new String[numrounds];

 List<NameValuePair> MynameValuePairs = new ArrayList<NameValuePair>(2);
 MynameValuePairs.add(new BasicNameValuePair("mynameis", "tam"));

 PostRequest.setEntity(new UrlEncodedFormEntity(MynameValuePairs));

 int i = 0;
 long timestart, DT;
 while(i < numrounds)
 {
  timestart = System.currentTimeMillis();
  POSTResult[i] = httpclient.execute(PostRequest, MyBRH);
  DT = System.currentTimeMillis() - timestart;
  Log.d(TAG, "(" + i + ") POST-Round Trip was "+ DT + " ms.");
  i++;
 }//while i <= numrounds
 httpclient.getConnectionManager().shutdown();
 return POSTResult;
} // END HTTPPOSTIt

These are called by:

Runnable HTTPGETJob = new HTTPGETTask(NS);
Thread HTTPGETThread = new Thread(HTTPGETJob, "HTTPGETThread");
HTTPGETThread.setPriority(Thread.MAX_PRIORITY);
HTTPGETThread.start();

and:

Runnable HTTPPOSTJob = new HTTPPOSTTask(NS);
Thread HTTPPOSTThread = new Thread(HTTPPOSTJob, "HTTPPOSTThread");
HTTPPOSTThread.setPriority(Thread.MAX_PRIORITY);
HTTPPOSTThread.start();

With runnables:

class HTTPGETTask implements Runnable
{
 int numtimes;
 DeviceInfo tsrtDI;
 HTTPGETTask(int inNS) {
  this.numtimes = inNS;
 }

 @Override
 public void run() 
 {
  long [] TT2NS = new long[numtimes];
  TT2NS = HTTPGETIt(numtimes);
 }
};

and,

class HTTPPOSTTask implements Runnable
{
 int numtimes;
 DeviceInfo tsrtDI;
 HTTPPOSTTask(int inNS) {
  this.numtimes = inNS;
 }

 @Override
 public void run() 
 {
  long [] TT2NS = new long[numtimes];
  TT2NS = HTTPPOSTIt(numtimes);
 }
};  

The output is typically:

(0) GET-Round Trip was 368 ms.

(1) GET-Round Trip was 103 ms.

(2) GET-Round Trip was 98 ms.

(3) GET-Round Trip was 106 ms.

(4) GET-Round Trip was 102 ms.


(0) POST-Round Trip was 1289 ms.

(1) POST-Round Trip was 567 ms.

(2) POST-Round Trip was 589 ms.

(3) POST-Round Trip was 496 ms.

(4) POST-Round Trip was 557 ms.

like image 722
Tam Avatar asked Jun 13 '12 04:06

Tam


1 Answers

I would insist you to set the Protocol Version as HTTP 1.1 and give it a try. It would increase request/response time than what it takes now. I haven't tried it though, just got the info. So, you can try something like below before executing the request.

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                                        HttpVersion.HTTP_1_1);
like image 102
Lalit Poptani Avatar answered Sep 19 '22 23:09

Lalit Poptani