2015-12-15 41 views
5

Tworzę małą aplikację do pomiaru czasu ładowania dokumentu HTML, sprawdzając co x liczbę sekund.Używanie Jsoup connect() w pętli. Pierwsze żądanie jest zawsze znacznie wolniejsze niż wszystkie kolejne.

Używam jsoup w pętli:

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); 
    } 

Problem mam jest, że pierwsze wykonanie połączenia jsoup jest zawsze wolniej niż cały kolejny raz, bez względu na stronie internetowej.

Oto moje wyjście na 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 

Oto co mam na http://stackoverflow.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 

Dlaczego to zawsze szybciej po pierwszym połączyć? Czy istnieje lepszy sposób określenia szybkości ładowania dokumentu?

+1

Może to pomoże: http://stackoverflow.com/questions/16994628/jsoup-seems-to- be-caching-can-i-disable-this – acdhirr

Odpowiedz

3

1. Jsoup musi uruchomić kod płyty kotła przed pierwszym żądaniem może zostać uruchomiony. Nie wliczałbym pierwszej prośby do twoich pomiarów, ponieważ cała inicjalizacja skośny zajmie pierwszą godzinę.

2. Jak wspomniano w komentarzach, wiele witryn pamięci podręcznej odpowiedzi na kilka sekund. W zależności od strony internetowej, którą chcesz zmierzyć, możesz użyć kilku sztuczek, aby serwer WWW mógł utworzyć świeżą witrynę za każdym razem. Taka sztuczka może polegać na dodaniu parametru timestamp. Zwykle używa się do tego _ (np. http://url/path/?pameter1=val1&_=ts). Lub możesz wysłać bez nagłówków pamięci podręcznej w żądaniu HTTP. jednak żadna z tych sztuczek nie może zmusić serwera WWW do zachowania się tak, jak tego chcesz. Możesz więc czekać dłużej niż 30 sekund pomiędzy każdą prośbą.

+0

Skończyło się na tym, że ignorował pierwsze żądanie i dodał kilka nagłówków, aby zapobiec buforowaniu. Dzięki! – Andrio

2

Myślę, że oprócz punktów @luksch jest jeszcze jeden czynnik, myślę, że Java utrzymuje połączenie na żywo przez kilka sekund, być może oszczędzając czas w podróżach protokołowych.

Jeśli użyjesz .header("Connection", "close"), zobaczysz więcej spójnych czasów.

Możesz sprawdzić, czy połączenia są utrzymywane przy użyciu sniffera. Przynajmniej widzę numery portów (mam na myśli port źródłowy, oczywiście) ponownie wykorzystane.

EDIT:

Inną rzeczą, która może dodać czas na pierwsze żądanie jest wyszukiwanie DNS ...

+0

Prawda. Wszystkie rzeczy, o których zapomniałem wspomnieć. +1 – luksch