2012-08-17 26 views
15

En mi código de rol de Azure, descargo un archivo de 400 megabytes que se divide en fragmentos de 10 megabytes y se almacena en Blob Storage. Yo uso CloudBlob.DownloadToStream() para la descarga.¿Por qué escribir en un MemoryStream es más lento que en un archivo?

Intenté dos opciones. Uno está usando un FileStream - creo un "write" FileStream y descargo trozos uno por uno en la misma corriente sin rebobinar y así termino con un archivo original. La otra opción es crear un objeto MemoryStream pasando un número ligeramente mayor que el tamaño del archivo original como el tamaño de la secuencia (para evitar reasignaciones) y descargando los fragmentos en ese MemoryStream - de esta manera termino con un MemoryStream que contiene los datos del archivo original.

aquí hay algo de pseudocódigo:

var writeStream = new StreamOfChoice(params); 
foreach(uri in urisToDownload) { 
    blobContainer.GetBlobReference(uri).DownloadToStream(writeStream); 
} 

Ahora, la única diferencia es que se trata de un FileStream en un caso y un MemoryStream en el otro, todo el resto es el mismo. Resulta que tarda unos 20 segundos con un FileStream y unos 30 segundos con un MemoryStream - sí, el FileStream resulta ser más rápido. De acuerdo con el contador de rendimiento \Memory\Available Bytes, la máquina virtual tiene aproximadamente 1 gigabyte de memoria disponible en el momento anterior a la creación de MemoryStream, por lo que no se debe a paginación.

¿Por qué escribir en un archivo sería más rápido que en un MemoryStream?

+4

¿Estás seguro de que tu flujo de memoria no se está intercambiando? – Oded

+0

Interesante pregunta: si no hay buscapersonas, MemoryStream debería ser mucho más rápido. ¿Qué tamaño de instancia estás usando? Y podría publicar algún código (incluso si esto probablemente no importa ya que simplemente está llamando a la biblioteca de Storage Client). –

+2

¿Tiene 1 GB de memoria * física * o 1 GB de memoria * virtual *? – Servy

Respuesta

3

Jon está probablemente en el balón allí. El más probable explicación es,

  1. La memoria es en realidad paginado a cabo por el hipervisor en el disco.
  2. El archivo de intercambio de hipervisor se encuentra en un disco de menor velocidad (por ejemplo, disco local).
  3. El sistema de archivos de la máquina virtual está en un disco empresarial rápido (digamos SAN).

Independientemente de si la memoria es más rápida o no, no debería asignar grandes bloques de memoria. Lea sobre LOH vs SOH aquí.

+0

Bueno, si los discos implicados tuvieran la misma velocidad (o el mismo disco), todavía esperaríamos que la escritura de archivos superara a la escritura de archivos de página, porque la escritura de archivos sería secuencial, que es el caso de cualquier plato giratorio basado disco (ya sea simple o RAID, pero sin incluir SSD) es mejor en el caso secuencial. Las paginas tienden a no doler mucho la mayor parte del tiempo debido a la inteligencia que se genera cuando se hace, por lo que la memoria paginada supera el acceso a los archivos en la mayoría de los casos, pero no en este. –

+0

No estoy de acuerdo. La paginación a la que me refiero es la paginación del hipervisor más bien que la paginación del OS. No son una y la misma cosa. El intercambio de hipervisores es sustancialmente más costoso ya que no puede saber qué páginas son las más adecuadas para paginar. En segundo lugar, la búsqueda de hipervisor se realiza con frecuencia en implementaciones a gran escala ubicadas en el disco local del servidor en lugar de en un almacenamiento compartido mucho más rápido. –

+0

Ninguno de los dos está en desacuerdo con el otro. 1: almacenamiento SANS> paginación HV. 2: Secuencial en disco> aleatorio en disco. Ellos pueden ser totalmente ciertos. –

1

Al usar MemoryStream en modo de depuración (VS), la velocidad es muy lenta, incluso con pequeñas cantidades de datos. Ejecutar sin depurador conectado es comparable o incluso más rápido que FileStream.

Primero me confundí y terminé aquí. Ahora estoy bien con MemoryStream.

Cuestiones relacionadas