9

Al fine di ottenere il trasferimento più veloce accelera su TCP in Java, che è meglio:Socket: BufferedOutputStream o solo OutputStream?

Opzione A:

InputStream in = socket.getInputStream(); 
OutputStream out = socket.getOutputStream(); 

Opzione B:

BufferedInputStream in = new BufferedInputStream(socket.getInputStream()); 
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 

Ho letto che le prestazioni prende un colpo quando si scrive su 8 KiB su OutputStream, si consigliava di scriverlo in piccoli blocchi non 8 KiB alla volta. 8 KiB è la dimensione del buffer predefinita di un BufferedOutputStream.

Tuttavia, ho anche letto che quando si trasferiscono i dati sulla rete è bene svuotare i byte il più rapidamente possibile. Significa che usare un buffer e scrivere in piccoli pezzi aggiunge un sovraccarico non necessario.

Quindi, l'opzione A o l'opzione B? Quale funziona meglio?

In questo momento sto indovinando l'opzione A offre le più elevate velocità di trasferimento mentre consuma molta più CPU rispetto all'opzione B. L'opzione B potrebbe essere migliore dato che non va molto più lentamente ma risparmia un sacco di CPU.

-

Bonus domanda: E 'una buona idea di toccare la dimensione della finestra TCP? Per esempio impostandolo su 64 KiB:

socket.setReceiveBufferSize(65536); 
socket.setSendBufferSize(65536); 

ho provato a installare a 128 KiB su una macchina di prova da quando ho letto che potrebbe aumentare la velocità, ma quando il server ha un paio di connessioni CPU erano al 100% invece di ~ 2% come quando l'ho lasciato da solo. Immagino che 128 KiB siano troppo alti a meno che tu non abbia un buon server in grado di gestire il traffico in fretta, ma è intelligente impostarlo su qualcosa come 32 KiB? Penso che il default fosse 8 KiB lì per me.

("presa" è "java.net.Socket")

risposta

6

Non so dove hai letto tutte quelle sciocchezze ma è completamente nuovo alla parte anteriore. Più scrivi in ​​un momento su una connessione TCP, meglio è, e più leggi da esso in un momento idem. Userei sempre un flusso bufferizzato, un lettore o uno scrittore tra l'applicazione e i flussi di socket. Ci sono alcuni casi come SSL dove scrivere direttamente un byte alla volta può causare un'esplosione di dati 40x.

È consigliabile toccare la dimensione della finestra TCP? Ad esempio impostandolo su 64 KiB

Non è possibile "toccare la dimensione della finestra TCP". Puoi aumentare il suo valore massimo tramite le API menzionate e questa è davvero una buona idea.

+0

L'utilizzo del core OutputStream e InputStream non obbliga a scrivere byte uno per uno. Che dire della scrittura di matrici di byte usando queste classi rispetto al buffering? – Mishax

0

Cosa intendi per velocità? bassa latenza o alto throughput?

Per bassa latenza, svuota lo stream non appena hai finito di scriverlo.

Per un throughput elevato, utilizzare un flusso bufferizzato e consentire a VM/OS di gestirne lo svuotamento.

Problemi correlati