2010-10-28 18 views
6

Estoy cargando un List<Image> desde una carpeta de aproximadamente 250 imágenes. Hice una comparación DateTime y lleva 11 segundos completos para cargar esas 250 imágenes. Eso es lento como el infierno, y me gustaría acelerarlo.Acelerando la carga de una Lista de imágenes

Las imágenes están en mi disco duro local, ni siquiera en uno externo.

El código:

DialogResult dr = imageFolderBrowser.ShowDialog(); 
if(dr == DialogResult.OK) { 

    DateTime start = DateTime.Now; 

    //Get all images in the folder and place them in a List<> 
    files = Directory.GetFiles(imageFolderBrowser.SelectedPath); 
    foreach(string file in files) { 
     sourceImages.Add(Image.FromFile(file)); 
    } 
    DateTime end = DateTime.Now; 

    timeLabel.Text = end.Subtract(start).TotalMilliseconds.ToString(); 
} 

EDIT: Sí, necesito todas las imágenes. Lo que estoy planeando es tomar el centro de 30 píxeles de cada uno y hacer una nueva imagen de eso. Un poco como una imagen de 360 ​​grados. Solo ahora, solo estoy probando con imágenes aleatorias.

Sé que hay probablemente mejores marcos para hacerlo, pero necesito que esto funcione primero.

EDIT2: Cambiado a un cronómetro, la diferencia es solo unos pocos milisegundos. También lo intenté con Directory.EnumerateFiles, pero no hubo ninguna diferencia.

EDIT3: Estoy ejecutando .NET 4, en un cliente Win7 de 32 bits.

+1

Ni siquiera voy a mirar el código todavía. ¡Siempre que haga benchmarks de rendimiento, no use DateTime! Use un objeto Cronómetro en su lugar. Son mucho más precisos y confiables. –

+0

Generalmente usaría un cronómetro para hacer el cronometraje. Encontrado en system.diagnostics. –

+0

Tipo de tangencial a su pregunta, pero para medir el tiempo de duración de las operaciones en su código [system.diagnostics.stopwatch] (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) funciona mucho mejor. –

Respuesta

1

Como cargar una imagen hace que tanto el IO como la CPU funcionen, debería obtener algo de aceleración utilizando más de un hilo.

Si está utilizando .net 4, el uso de tareas sería el camino a seguir.

3

¿De verdad necesita cargar todas las imágenes? ¿Puedes salirte con la carga con pereza? Alternativamente, ¿puedes cargarlos en un hilo separado?

1

Dado que es probable que ya conozca la ruta (¿desde el cuadro de diálogo?), Podría ser mejor utilizar Directory.EnumerateFiles y luego trabajar con la colección que devuelve en lugar de una lista.

http://msdn.microsoft.com/en-us/library/dd383458.aspx

[editar]

di cuenta de que también va a cargar los archivos en su aplicación dentro del bucle - lo grande que son? Dependiendo de su tamaño, ¡podría ser una velocidad bastante buena!

¿Necesita cargarlos en este punto? ¿Se puede cambiar el código de visualización en otro lugar para cargar según demanda?

+0

Lo probé, pero no hay diferencia de velocidad. También cambié a un cronómetro, la diferencia es de unos pocos milisegundos. – KdgDev

2

No puede acelerar el acceso a su HDD y la velocidad de decodificación. Sin embargo, una buena idea sería cargar las imágenes en un hilo de fondo.

Quizás debería considerar mostrar un marcador de posición hasta que la imagen se cargue realmente.

Atención: ¡tendrá que insertar las imágenes cargadas en su subproceso de IU de todos modos!

+2

Bueno, eso no es completamente cierto. Él podría reemplazarlo con un SSD. – jason

+0

@Jason: Quise decir, programáticamente :-D – Vlad

+0

+1 para la sugerencia de mostrar el marcador de posición mientras se cargan las imágenes en un hilo de fondo. –

2

Puede usar Directory.EnumerateFiles junto con Parallel.ForEach para distribuir el trabajo en tantas CPU como tenga.

var directory = "C:\\foo"; 
var files = Directory.EnumerateFiles(directory, "*.jpg"); 
var images = files.AsParallel().Select(file => Image.FromFile(file)).ToList(); 
+0

Eso supone que está usando .NET4.0 –

0

Probablemente no pueda acelerar las cosas ya que el cuello de la botella está leyendo los archivos del disco y tal vez los analiza como imágenes.

Lo que puedes hacer es guardar en la memoria caché la lista después de cargarla y luego cualquier llamada subsiguiente a tu código será mucho más rápida.