在循环中使用 Jsoup connect()。第一个请求总是比所有其他后续请求慢得多

Using Jsoup connect() in a loop. The first request is always much slower than all other subsequent ones

我正在创建一个小应用程序来测量加载 HTML 文档需要多长时间,每隔 x 秒检查一次。

我在循环中使用 jsoup:

    Connection.Response response = null;

    for (int i = 0; i < totalGets; i++) {
        long startTime = System.currentTimeMillis();

        try {
            response = Jsoup.connect(url)
                    .userAgent(USER_AGENT)  //just using a Firefox user-agent
                    .timeout(30_000)
                    .execute();
        } catch (IOException e) {
            if (e.getMessage().contains("connect timed out")) {
                System.out.println("Request timed out after 30 seconds!");
            }
        }

        long currentTime = System.currentTimeMillis();

        System.out.println("Response time: " + (currentTime - startTime) + "ms" + "\tResponse code: " + response.statusCode());

        sleep(2000);
    }

我遇到的问题是,jsoup 连接的第一次执行总是比随后的所有执行都慢,无论是哪个网站。

这是我在 https://www.google.com

上的输出
Response time: 934ms    Response code: 200
Response time: 149ms    Response code: 200
Response time: 122ms    Response code: 200
Response time: 136ms    Response code: 200
Response time: 128ms    Response code: 200

这是我在 http://whosebug.com

上看到的
Response time: 440ms    Response code: 200
Response time: 182ms    Response code: 200
Response time: 187ms    Response code: 200
Response time: 193ms    Response code: 200
Response time: 185ms    Response code: 200

为什么第一次连接后速度总是更快?有没有更好的方法来确定文档的加载速度?

1. 在触发第一个请求之前,Jsoup 必须 运行 一些样板代码。我不会将第一个请求计入您的测量值,因为所有初始化都会影响第一个请求时间。

2. 如评论中所述,许多网站会将响应缓存几秒钟。根据您要测量的网站,您可以使用一些技巧让网络服务器每次都生成一个新网站。这样的技巧可能是添加时间戳参数。通常 _ 用于此(如 http://url/path/?pameter1=val1&_=ts)。或者您可以在 HTTP 请求中不发送缓存 headers。然而,none 这些技巧可以强制网络服务器按照您想要的方式运行。因此您可以在每个请求之间等待超过 30 秒。

我认为除了@luksch 点之外还有另一个因素,我认为 Java 保持连接 几秒钟,可能会节省协议时间旅行。

如果您使用 .header("Connection", "close"),您会看到更一致的时间。

您可以使用嗅探器检查连接是否保持活动状态。至少我可以看到重用的端口号(我指的当然是源端口)。

编辑:

另一个可能会增加第一次请求时间的事情是 DNS 查找 ...

另一个可能的原因是 JVM 在后台进行 JIT 优化,将 java 字节代码转换为本机指令以提高速度。

第一次 运行 代码速度很慢,因为代码尚未优化。由于优化已经完成,因此接下来的回合会更快。

解析 html 页面是一项计算密集型工作。