2010-01-21 15 views
7

Ho scritto un servizio WCF che dovrebbe trasformare qualsiasi dimensione di file, utilizzando la Modalità trasferimento trasmessa negli oggetti NetTcpBinding e System.IO.Stream.WCF NetTcpBinding Buffered vs Problemi di prestazioni in streaming

Durante l'esecuzione del test delle prestazioni, ho riscontrato un notevole problema di prestazioni. Poi ho deciso di testarlo con Buffered TransferMode e ho visto che le prestazioni sono due volte più veloci!

Poiché il mio servizio deve trasferire file di grandi dimensioni, non riesco a rimanere in Buffered TransferMode a causa del sovraccarico di gestione della memoria su file di grandi dimensioni sul lato server e lato client.

Perché la modalità di trasferimento trasferita è più lenta della modalità trasferimento bufferizzata? Cosa posso fare per migliorare le prestazioni di Stremed?

+0

Che cosa esattamente ha fatto si misura? Il trasporto del messaggio? Un viaggio di andata e ritorno da un cliente all'altro con una risposta al cliente? – GaussZ

+0

Misuro la chiamata al server e aspetto che venga restituito Stream, quindi leggo tutto il flusso con 64k di buffer nell'utilizzo del blocco. – DxCK

+0

@DxCK: ora qual è la tua opinione? Quale dovrebbe essere usato? Ho sia grandi che piccole dimensioni di dati da trasferire. – Sreekumar

risposta

6

Quanto sono grandi i blocchi che stai trasmettendo? È possibile sperimentare con diverse dimensioni del blocco e strategie diverse.
Inoltre, considerare l'utilizzo di Asynch IO per riempire i buffer da trasferire o dopo il trasferimento.

Quello che voglio dire è che, se il vostro algoritmo di streaming è di serie, in questo modo:

1. Fill a chunk 
2. send the chunk 
3. get confirmation 
4. more chunks? Go to step 1 

... allora hai un sacco di inutili ritardi. Se riesci a riempire blocchi e inviare blocchi in parallelo, sarai in grado di ridurre l'attesa. L'IO asincrono è un modo per farlo. Avresti due flussi di lavoro paralleli in corso. Concettualmente, potrebbe assomigliare a questo:

Filling Chunks        Sending Chunks 
    1. call BeginRead       1. get next chunk 
    2. wait for callback      2. send it 
    3. more to read? yes -> go to step 1  3. await confirmation 
    4. done          4. more? go to step 1 

Ma usando IO asincrono, questi potrebbe effettivamente essere guidato dallo stesso thread.

Tenetelo a mente:

alt text http://i45.tinypic.com/t82r92.jpg

Hai letto MS's article on the topic of large data streaming in WCF?

+0

Il mio test non ha altri I/O oltre a WCF. Il flusso trasferito contiene byte casuali rispetto a quelli creati con il metodo Random.NextBytes(). comunque, esattamente lo stesso codice funziona più velocemente solo con la modifica della configurazione su "Buffered". – DxCK

+0

Sostituisci "IO" nei miei commenti con "Random.NextBytes()" e il principio è ancora valido. Nel tuo caso, esegui un Random.NextBytes() su una piccola porzione alla volta? In tal caso, considerare l'utilizzo dell'asincronia per eliminare la serializzazione delle operazioni. – Cheeso

+0

Ho eseguito Random.NextBytes() in varie dimensioni: 64k, 350k, 512k, 1MB, 2MB, 5MB, 10MB, quindi creato un MemoryStream e fornito lo stream a WCF. WCF fa tutto il resto (legge ecc.) L'altro lato (server o client) sta leggendo il flusso, non ho visto differenze di prestazioni tra le varie dimensioni del buffer. I risultati sono simili con tutte quelle dimensioni: Buffered è 2 volte più veloce di Streaming. – DxCK

Problemi correlati