Rychlost síťových operací v Javě
Ne všechny operace v Javě trvají stejnou dobu. Pro efektivní využití zdrojů je nutné využít nástrojů, jež jsou doporučeny od tvůrců jazyka. Uveďme si jednoduchý příklad a ukažme si srovnání jeho účinnosti. Mějme jednoduchý server, který čeká na klienty. Po připojení klienta mu odešle 2 000 000 bajtů a spojení ukončí. Klient příjme data, zahodí je a změří, jak dlouho mu příjem trval. Porovnáme 2 základní metody pro psaní programů.
Server
Server je popsaný následujícím kódem, který se provede pro každého klienta.
Pomalá verze
OutputStream os = socket.getOutputStream(); for (int i = 0; i < 2000000; i++) { os.write((byte)0x30); }
Rychlá verze
OutputStream os = s.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os)); for (int i = 0; i < 2000000; i++) { bw.write('a'); }
Klient
Klient pouze přečte data od serveru a vypíše jak dloho mu to trvalo.
Pomalá verze
InputStream is = socket.getInputStream(); int c; while((c=is.read())!=-1){ // do nothing }
Rychlá verze
InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); int c; while((c=br.read())!=-1){ // do nothing }
Tabulka s výsledky
Klient | Server | |
---|---|---|
Pomalý | Rychlý | |
Pomalý | 9800 | 5200 |
Rychlý | 9650 | 320 |
Doba běhu je uvedena v ms.
Poučení
Čtení ze souborů nebo sítě pomocí funkcí InputStream.read() je náročné na čas. Proto je nutné použít obalové třídy BufferedReader, která omezuje počet časově náročných čtení ze souboru či sítě.
P.S. BufferedReader.readLine() je úžasná funkce, ale pro implementaci Karla se opravdu nehodí…