You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by "Kalnichevski, Oleg" <ol...@bearingpoint.com> on 2004/08/20 15:29:22 UTC

Performance HttpClient 2.0.1 vs HttpClient 2.0-alpha3 vs HttpURLConnection jre1.4

All right. I ran a few tests to see how well (or badly) HttpClient measures up to the performance if HttpURLConnection shipped with JRE1.4 (v1.4.2.3)

Test platform: Win2k (PIII 512MB) + Tomcat 4.1.29 (JDK1.4.2.3 Xms128M Xmx256M) running locally
Test code attached below

There are the results

======================================================================
HttpClient 2.0.1 vs HttpURLConnection 1.4.2

(Note: stale connection check has been disabled)

Average GET time with HttpClient, payload ~150 byte: 5 ms
Average GET time with HttpURLConnection, payload ~150 byte: 2 ms
Average GET time with HttpClient, payload ~12,000 byte: 4 ms
Average GET time with HttpURLConnection, payload ~12,000 byte: 3 ms
Average POST time with HttpClient, payload ~300,000 byte: 867 ms
Average POST time with HttpURLConnection, payload ~300,000 byte: 996 ms

======================================================================
HttpClient 2.0alpha3 vs HttpURLConnection 1.4.2

Average GET time with HttpClient, payload ~150 byte: 4 ms
Average GET time with HttpURLConnection, payload ~150 byte: 2 ms
Average GET time with HttpClient, payload ~12,000 byte: 4 ms
Average GET time with HttpURLConnection, payload ~12,000 byte: 2 ms
Average POST time with HttpClient, payload ~300,000 byte: 1168 ms
Average POST time with HttpURLConnection, payload ~300,000 byte: 1031 ms

======================================================================
Summary:
(1) HttpClient 2.0.1 is somewhat slower for smaller GETs, but the difference in performance is almost constant (1-3 ms), which is IMHO is fair price to pay for a significantly feature-rich API that HttpClient provides. HttpClient 2.0.1 is somewhat faster than HttpURLConnection for larger GETs and is significantly faster than HttpURLConnection for bulky POSTs when request body is streamed out unbuffered.
(2) With the stale connection check disabled HttpClient 2.0.1 performs better than HttpClient 2.0alpha3

IMHO HttpClient clearly performs reasonably well in all cases but for tiny GETs, and it performs better than HttpURLConnection in more complex cases where its better architecture shows.

Please let me know if you see any flaws in the way tests had been setup or have hints on how to further optimize HttpURLConnection performance

Oleg


=======================================================================

import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

public class PerfTest {

    public static void main(String args[]) throws Exception {
        System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
        System.setProperty("org.apache.commons.logging.simplelog.log", "error");

        URL targeturl1 = new URL("http://localhost:8080/httpclienttest/body");
        URL targeturl2 = new URL("http://localhost:8080/tomcat-docs/index.html");
       
        // Performance optimization for HttpClient
        SimpleHttpConnectionManager connmanager = new SimpleHttpConnectionManager();
        connmanager.setConnectionStaleCheckingEnabled(false);
        HttpClient httpclient = new HttpClient(connmanager);
        httpclient.setConnectionTimeout(0);

        int N = 2000;

        long total = 0;
       
        for (int i = 0; i < N; i ++) {

            long start = System.currentTimeMillis();
            GetMethod httpget = new GetMethod(targeturl1.toExternalForm());
            try {
                httpclient.executeMethod(httpget);
                httpget.getStatusCode();
                consumeResponse(httpget.getResponseBodyAsStream());
            } finally {
                httpget.releaseConnection();
            }
            long end = System.currentTimeMillis();
            total += (end - start);
        }
        System.out.println("Average GET time with HttpClient, payload ~150 byte: "
                + (total / N) + " ms");
       
        total = 0;
        for (int i = 0; i < N; i ++) {
            long start = System.currentTimeMillis();
            HttpURLConnection httpURLConnection = (HttpURLConnection) targeturl1.openConnection();
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setAllowUserInteraction(false);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.connect();
            httpURLConnection.getResponseCode();
            consumeResponse(httpURLConnection.getInputStream());
            long end = System.currentTimeMillis();
            total += (end - start);
        }
        System.out.println("Average GET time with HttpURLConnection, payload ~150 byte: "
                + (total / N) + " ms");

        N = 1000;
        total = 0;
        for (int i = 0; i < N; i ++) {
            long start = System.currentTimeMillis();
            GetMethod httpget = new GetMethod(targeturl2.toExternalForm());
            try {
                httpclient.executeMethod(httpget);
                httpget.getStatusCode();
                consumeResponse(httpget.getResponseBodyAsStream());
            } finally {
                httpget.releaseConnection();
            }
            long end = System.currentTimeMillis();
            total += (end - start);
        }
        System.out.println("Average GET time with HttpClient, payload ~12,000 byte: "
                + (total / N) + " ms");

        total = 0;
        for (int i = 0; i < N; i ++) {
            long start = System.currentTimeMillis();
            HttpURLConnection httpURLConnection = (HttpURLConnection) targeturl2.openConnection();
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setAllowUserInteraction(false);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.connect();
            httpURLConnection.getResponseCode();
            consumeResponse(httpURLConnection.getInputStream());
            long end = System.currentTimeMillis();
            total += (end - start);
        }
        System.out.println("Average GET time with HttpURLConnection, payload ~12,000 byte: "
                + (total / N) + " ms");

       File file = new File("stuff");
           
       N = 200;
       total = 0;
       for (int i = 0; i < N; i ++) {
            long start = System.currentTimeMillis();
            PostMethod httppost = new PostMethod(targeturl1.toExternalForm());
            httppost.setRequestBody(new FileInputStream(file));
            httppost.setRequestContentLength((int)file.length());
            try {
                httpclient.executeMethod(httppost);
                httppost.getStatusCode();
                consumeResponse(httppost.getResponseBodyAsStream());
            } finally {
                httppost.releaseConnection();
            }
            long end = System.currentTimeMillis();
            total += (end - start);
       }
       System.out.println("Average POST time with HttpClient, payload ~300,000 byte: "
               + (total / N) + " ms");
           
       total = 0;
       for (int i = 0; i < N; i ++) {
            long start = System.currentTimeMillis();
            HttpURLConnection httpURLConnection = (HttpURLConnection) targeturl1.openConnection();
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setAllowUserInteraction(false);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setRequestMethod("POST");
            postRequest(httpURLConnection.getOutputStream(), file);
            httpURLConnection.connect();
            httpURLConnection.getResponseCode();
            consumeResponse(httpURLConnection.getInputStream());
            long end = System.currentTimeMillis();
            total += (end - start);
           
        }
       System.out.println("Average POST time with HttpURLConnection, payload ~300,000 byte: "
               + (total / N) + " ms");
    }
   
    private static byte[] consumeResponse(final InputStream instream) throws IOException {
       
        ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
        int l = -1;
        byte[] tmp = new byte[1024];
        while ((l = instream.read(tmp)) >= 0) {
            buffer.write(tmp, 0, l);
        }
        return buffer.toByteArray();
    }

    private static void postRequest(final OutputStream outstream, final File file)
        throws IOException {
       
        FileInputStream instream = new FileInputStream(file); 
        int l = -1;
        byte[] tmp = new byte[1024];
        while ((l = instream.read(tmp)) >= 0) {
            outstream.write(tmp, 0, l);
        }
    }
}





-----Original Message-----
From: Kalnichevski, Oleg
Sent: Friday, August 20, 2004 9:39 AM
To: Commons HttpClient Project
Subject: RE: HttpClient performance



Zulfi,

If you expect us to react on this report, you have to be a little more specific on how exactly you measured the performance, exactly what kind of HTTP methods your tests included, exactly what pre-release-candidate you are referring to, and what exactly you mean by "but it is still slower than using JDK-1.4.2". Do you actually mean using HttpURLConnection? Raw socket? Something else?

I'll run a few tests of my own to see if I get significant difference in terms of performance between HttpClient 2.0alpha3, 2.0.1, CVS HEAD (post-3.0a1) and HttpURLConnection

Oleg


-----Original Message-----
From: Zulfi Umrani [mailto:zumrani@novell.com]
Sent: Friday, August 20, 2004 7:06 AM
To: commons-httpclient-dev@jakarta.apache.org
Subject: HttpClient performance


Hi,

Just wanted to get the latest information on the performance issues
reported earlier. I have gone through the below emails from Archive, but
could not get a definite solution to the performance problem. Wondering
whether a definite solution was found and whether there is a patch
available. We tested the performance using pre-release-candidate version
of HttpClient(2.0) and it was much better than the release-candidate
versions and the final 2.0 version of HttpClient. Please note that I did
try using the  SimpleHttpConnectionManager and calling the
setConnectionStaleCheckingEnabled method with false argument. The
performance does improve, but it is still slower than using JDK-1.4.2. I
will appreciate if someone who knows the solution can respond.
  


http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-httpclient-dev@jakarta.apache.org&msgId=781750
http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-httpclient-dev@jakarta.apache.org&msgId=781859
http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-httpclient-dev@jakarta.apache.org&msgId=781909
http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-httpclient-dev@jakarta.apache.org&msgId=779703

Thanks.



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-httpclient-dev-help@jakarta.apache.org


***************************************************************************************************
The information in this email is confidential and may be legally privileged.  Access to this email by anyone other than the intended addressee is unauthorized.  If you are not the intended recipient of this message, any review, disclosure, copying, distribution, retention, or any action taken or omitted to be taken in reliance on it is prohibited and may be unlawful.  If you are not the intended recipient, please reply to or forward a copy of this message to the sender and delete the message, any attachments, and any copies thereof from your system.
***************************************************************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-httpclient-dev-help@jakarta.apache.org


***************************************************************************************************
The information in this email is confidential and may be legally privileged.  Access to this email by anyone other than the intended addressee is unauthorized.  If you are not the intended recipient of this message, any review, disclosure, copying, distribution, retention, or any action taken or omitted to be taken in reliance on it is prohibited and may be unlawful.  If you are not the intended recipient, please reply to or forward a copy of this message to the sender and delete the message, any attachments, and any copies thereof from your system.
***************************************************************************************************

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-httpclient-dev-help@jakarta.apache.org