文章
本文总阅读量

Java Http工具类性能比较

Java Http工具类性能比较

测试环境java17,使用mock-server来作为https的服务端。分别测试okhttp3,hutool的http,以及spring的Resttemplate。使用idea的Profiler进行性能分析。

1.http性能对比

http对比代码 ```java public class HttpUtilsTest { private static ClientAndServer mockServer; SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); RestTemplate restTemplate = new RestTemplate(requestFactory); private static final int REQUEST_COUNT = 200000; @BeforeAll public static void startMockServer() { ConfigurationProperties.logLevel("WARN"); mockServer = ClientAndServer.startClientAndServer(1080); } @AfterAll public static void stopMockServer() { mockServer.stop(); } @Test public void testHutoolHttp() { mockServer .when(org.mockserver.model.HttpRequest.request().withMethod("GET").withPath("/test")) .respond(HttpResponse.response().withBody("Hello, world!")); int requestCount = REQUEST_COUNT; long startTime = System.nanoTime(); for (int i = 0; i < requestCount; i++) { HttpRequest.get("http://localhost:1080/test").execute(); } long endTime = System.nanoTime(); long responseTime = endTime - startTime; double averageResponseTime = responseTime / (double) requestCount; System.out.println("Average response time: " + averageResponseTime + " ns"); } @Test public void testOKHttp() throws IOException { mockServer .when(org.mockserver.model.HttpRequest.request().withMethod("GET").withPath("/test")) .respond(HttpResponse.response().withBody("Hello, world!")); OkHttpClient client = new OkHttpClient.Builder() .build(); Request request = new Request.Builder() .url("http://localhost:1080/test") .build(); int requestCount = REQUEST_COUNT; long startTime = System.nanoTime(); for (int i = 0; i < requestCount; i++) { okhttp3.Response response = client.newCall(request).execute(); response.body().close(); // 关闭响应体 } long endTime = System.nanoTime(); long responseTime = endTime - startTime; double averageResponseTime = responseTime / (double) requestCount; System.out.println("Average response time: " + averageResponseTime + " ns"); } @Test public void testRestTemplate() { mockServer .when(org.mockserver.model.HttpRequest.request().withMethod("GET").withPath("/test")) .respond(HttpResponse.response().withBody("Hello, world!")); long startTime = System.nanoTime(); for (int i = 0; i < REQUEST_COUNT; i++) { restTemplate.getForObject("http://localhost:1080/test", String.class); } long endTime = System.nanoTime(); long responseTime = endTime - startTime; double averageResponseTime = responseTime / (double) REQUEST_COUNT; System.out.println("Average response time: " + averageResponseTime + " ns"); } } ```

1.1 okhttp

client.newCall(request).execute();20w次循环,okhttp这段代码的花费的cpu时间为1841 ms,total time 15961ms,总共分配1.16GB

1.2 hutool

httpRequest.get("https://localhost:1080/test").execute();
20w次循环,hutool这段代码的花费的cpu时间为5443ms,total time 21680ms,总共分配达到6.45GB

1.3 RestTemplate

restTemplate.getForObject("https://localhost:1080/test", String.class);
20w次循环,hutool这段代码的花费的cpu时间为5199ms,total time 20032ms,总共分配达到6.11GB

1.4 对比小结

三者对比发现okhttp cpu时间消耗较少,并且内存分配较少。堆栈内存消耗,三者均在处于260MB-520MB之间。

2.https性能对比

使用idea的Profiler进行性能分析。 okhttp测试代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class OkHttpTest {

    private static ClientAndServer mockServer;

    @BeforeAll
    public static void startMockServer() {
        ConfigurationProperties.logLevel("WARN");
        HttpsURLConnection.setDefaultSSLSocketFactory(new KeyStoreFactory(new MockServerLogger()).sslContext().getSocketFactory());
        mockServer = ClientAndServer.startClientAndServer(1080);
    }

    @AfterAll
    public static void stopMockServer() {
        mockServer.stop();
    }

    @Test
    public void testPerformance() throws IOException {
        mockServer
                .when(HttpRequest.request().withMethod("GET").withPath("/test"))
                .respond(HttpResponse.response().withBody("Hello, world!"));

        OkHttpClient client = new OkHttpClient.Builder()
                .build();

        Request request = new Request.Builder()
                .url("https://localhost:1080/test")
                .build();

        long totalResponseTime = 0;
        int requestCount = 200000;
        long startTime = System.nanoTime();
        for (int i = 0; i < requestCount; i++) {
            client.newCall(request).execute();
        }
        long endTime = System.nanoTime();
        long responseTime = endTime - startTime;

        double averageResponseTime = responseTime / (double) requestCount;

        System.out.println("Average response time: " + averageResponseTime + " ns");
    }
}

测试循环发送20w次https请求。
Hutool以及Spring的Resttemplate只是替换了工具类的相关代码测试次数,以及其他部分均相同。

2.1 okhttp

client.newCall(request).execute();20w次循环,okhttp这段代码的花费的cpu时间为2791 ms,total time 25862ms,总共分配1.54GB,堆栈内存保持在260MB-420MB左右。

2.2 hutool

httpRequest.get("https://localhost:1080/test").execute();
20w次循环,hutool这段代码的花费的cpu时间为5498ms,total time 24743ms 总共分配达到6.85GB,堆栈内存保持在330MB-500MB左右。

2.3 RestTemplate

restTemplate.getForObject("https://localhost:1080/test", String.class);
20w次循环,restTemplate这段代码的花费的cpu时间为5790ms,total time 35812ms 总共分配达到6.52GB,堆栈内存保持在264MB-537MB左右。相比于另外两种restTemplate的totol time相比于其他两种耗时增加最多。

2.4 对比小结

初步对比看下来okhttp不管是在cpu时间,还是total time上都是处于较优的水平。hutool与RestTemplate因为误差存在,可以认为相差不大。

总结

工具类名称CPU时间 (ms)总时间 (ms)内存分配 (GB)堆栈内存 (MB)
OkHttp (HTTP)1841159611.16-
Hutool (HTTP)5443216806.45-
RestTemplate (HTTP)5199200326.11-
OkHttp (HTTPS)2791258621.54260-420
Hutool (HTTPS)5498247436.85330-500
RestTemplate (HTTPS)5790358126.52264-537

在时间消耗以及内存分配上,20w次请求,okHttp不管是在http还是https的get请求中,都处于领先位置。

本文由作者按照 CC BY 4.0 进行授权