Tengo una aplicación de Windows que descarga el archivo de rutina del servidor de equilibrio de carga, actualmente la velocidad es de aproximadamente 30 MB/segundo. Sin embargo, intento usar FastCopy o TeraCopy que puede copiar a aproximadamente 100 MB/segundo. Quiero saber cómo mejorar mi velocidad de copia para que pueda copiar el archivo más rápido que en la actualidad.Cómo hacer que mi aplicación copie el archivo más rápido
Respuesta
Un error común al usar flujos es copiar un byte a la vez, o usar un pequeño búfer. La mayor parte del tiempo que se tarda en escribir datos en el disco se utiliza para buscar, por lo que usar un búfer más grande reducirá el tiempo promedio de búsqueda por byte.
Los sistemas operativos escriben archivos en el disco en clústeres. Esto significa que cuando escribe un solo byte en el disco, Windows escribirá un bloque entre 512 bytes y 64 kb de tamaño. Puede obtener un rendimiento de disco mucho mejor si utiliza un búfer que es un múltiplo entero de 64 kb.
Además, puede obtener un impulso del uso de un búfer que es un múltiplo de sus CPU subyacentes al tamaño de la página de memoria. Para máquinas x86/x64 esto se puede configurar a 4kb o 4mb.
Así que desea utilizar un número entero múltiplo de 4mb.
Además, si utiliza IO asíncrono puede aprovechar al máximo el tamaño de búfer grande.
class Downloader
{
const int size = 4096 * 1024;
ManualResetEvent done = new ManualResetEvent(false);
Socket socket;
Stream stream;
void InternalWrite(IAsyncResult ar)
{
var read = socket.EndReceive(ar);
if (read == size)
InternalRead();
stream.Write((byte[])ar.AsyncState, 0, read);
if (read != size)
done.Set();
}
void InternalRead()
{
var buffer = new byte[size];
socket.BeginReceive(buffer, 0, size, System.Net.Sockets.SocketFlags.None, InternalWrite, buffer);
}
public bool Save(Socket socket, Stream stream)
{
this.socket = socket;
this.stream = stream;
InternalRead();
return done.WaitOne();
}
}
bool Save(System.Net.Sockets.Socket socket, string filename)
{
using (var stream = File.OpenWrite(filename))
{
var downloader = new Downloader();
return downloader.Save(socket, stream);
}
}
Posiblemente su aplicación puede hacer multi-threading para obtener el archivo con múltiples hilos, sin embargo, el ancho de banda está limitado a la velocidad de los dispositivos que transfieren el contenido
forma más sencilla es abrir el archivo en crudo/binaria modo (es que C no está seguro de cuál es el equivalente de C#) y lee y escribe bloques muy grandes (varios MB) a la vez.
El truco que utiliza TeraCopy es hacer que la lectura y la escritura sean asincrónicas. Esto significa que se puede escribir un bloque de datos mientras se lee otro.
Tienes que jugar con el número de bloques y el tamaño de esos bloques para obtener el óptimo para tu situación. Usé este método usando C++ y para nosotros el óptimo fue usar cuatro bloques de 256 KB cuando copiamos de un recurso compartido de red a un disco local.
Saludos,
Sebastiaan
Si ejecuta Process Monitor se puede ver los tamaños de bloque que el Explorador de Windows o TeraCopy está utilizando.
En Vista, el tamaño de bloque predeterminado para la red local es de 2 MB, lo que hace que copiar archivos a través de una tubería enorme sea mucho más rápido.
¿Por qué reinventar la rueda?
Si su situación lo permite, es probable que sea mejor desembolsar una de las utilidades de copia "rápidas" existentes que tratar de escribir una usted mismo. Hay numerosos casos extremos no obvios que deben manejarse, y obtener un buen rendimiento consistentemente requiere una gran cantidad de experimentación de error de final de prueba.
- 1. Cómo hacer que mi código sea rápido
- 2. ¿Cómo hacer que doxygen funcione más rápido?
- 3. ¿Cómo hacer que JVM arranque más rápido?
- 4. Hacer mi List.filter más rápido en Scala?
- 5. Cómo hacer que el emulador de Android arranque más rápido
- 6. ¿Cómo puedo hacer que mis anuncios aparezcan más rápido en mi aplicación de Android?
- 7. Hacer que JAXB vaya más rápido
- 8. Cómo hacer que el eclipse IDE se construya más rápido
- 9. ¿Cómo puedo hacer que Java3D comience más rápido?
- 10. ¿Cómo hacer que este script sed sea más rápido?
- 11. ¿Cómo puedo hacer que Quartus II compile más rápido?
- 12. ¿Cómo hacer que mis emacs personalizados carguen más rápido?
- 13. ¿Cómo es "mi" más rápido que "local" en Perl?
- 14. ¿Cómo hacer que este Twisted Python Proxy sea más rápido?
- 15. ¿Cómo puedo hacer que Matlab Compiler funcione más rápido?
- 16. ¿Cómo hacer que los fragmentos se carguen más rápido?
- 17. ¿Cómo hacer que un sitio web funcione más rápido?
- 18. ¿Cómo puedo hacer que mi caché. LRU simple sea más rápido?
- 19. ¿Es el archivo paralelo.Leer más rápido que la lectura secuencial?
- 20. ¿Cómo puedo hacer cout más rápido?
- 21. ¿Cómo hacer que Maven copie el archivo de recursos en el directorio WEB-INF/lib?
- 22. Más rápido que String.Replace()
- 23. ¿Es + = más rápido que - =?
- 24. ¿Puedo hacer que maven-assembly-plugin vaya más rápido?
- 25. Algo más rápido que get_headers()
- 26. Algo más rápido que HttpHandlers?
- 27. ¿Cómo puedo hacer que mi aplicación .NET se borre sola?
- 28. ¿Qué puede hacer que el código F # no optimizado sea más rápido que el código optimizado?
- 29. ¿Una forma de hacer que md5_file() sea más rápido?
- 30. Carga más rápida ListView, más rápido que el método Viewholder
¿Puedo utilizar utilidades de copia "rápidas" para scripts (línea de comando)? – Kiquenet
Al menos algunos son programables, robocopy es un ejemplo. – Addys