2010-10-28 6 views
6

Sto caricando un List<Image> da una cartella di circa 250 immagini. Ho fatto un confronto DateTime e ci sono voluti ben 11 secondi per caricare quelle 250 immagini. È lento come l'inferno, e mi piacerebbe molto accelerarlo.Accelerazione del caricamento di un elenco di immagini

Le immagini sono sul mio disco rigido locale, nemmeno su quello esterno.

Il codice:

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ì, ho bisogno di tutte le immagini. La cosa che sto pianificando è di prendere il centro di 30 pixel di ciascuna e di farne una nuova immagine. Un po 'come una foto a 360 gradi. Solo adesso, sto solo testando immagini casuali.

So che probabilmente ci sono quadri migliori per fare questo, ma ho bisogno che funzioni prima.

EDIT2: commutato a un cronometro, la differenza è di pochi millisecondi. Anche provato con Directory.EnumerateFiles, ma nessuna differenza.

EDIT3: eseguo .NET 4 su un client Win7 a 32 bit.

+1

Non ho ancora intenzione di guardare il codice ancora. Ogni volta che si eseguono benchmark delle prestazioni, non utilizzare DateTime! Utilizzare invece un oggetto Cronometro. Sono molto più precisi e affidabili. –

+0

Generalmente userei un cronometro per fare i tempi. Trovato in system.diagnostics. –

+0

Tipo di tangente alla tua domanda ma per il tempismo per quanto tempo le operazioni eseguono il tuo codice [system.diagnostics.stopwatch] (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) funziona molto meglio. –

risposta

1

Poiché il caricamento di un'immagine fa funzionare sia il file IO che la CPU, è necessario ottenere un po 'di speadup utilizzando più di un thread.

Se si utilizza .net 4, utilizzare le attività sarebbe la strada da percorrere.

3

Avete effettivamente bisogno di caricare tutte le immagini? Puoi farcela a caricarli pigramente? In alternativa, puoi caricarli su un thread separato?

1

Dato che probabilmente conosci già il percorso (dalla finestra di dialogo?), Potresti utilizzare Directory.EnumerateFiles e quindi utilizzare la raccolta restituita anziché un elenco.

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

[modifica]

appena notato che stai anche caricando il file nel tuo app all'interno del ciclo - come sono grandi? A seconda delle loro dimensioni, potrebbe effettivamente essere una buona velocità!

Hai bisogno di caricarli a questo punto? È possibile modificare qualche codice di visualizzazione altrove per il caricamento su richiesta?

+0

L'ho provato, ma non c'è differenza di velocità. Sono passato anche a un cronometro, la differenza è di pochi millisecondi. – KdgDev

2

Non è possibile accelerare la velocità di accesso e decodifica dell'HDD. Comunque una buona idea sarebbe quella di caricare le immagini in un thread in background.

Forse dovresti considerare di mostrare un segnaposto finché l'immagine non viene effettivamente caricata.

Attenzione: è necessario inserire le immagini caricate nella filettatura dell'interfaccia utente comunque!

+2

Beh, non è completamente vero. Potrebbe sostituirlo con un SSD. – jason

+0

@Jason: intendevo, a livello di codice :-D – Vlad

+0

+1 per il suggerimento di mostrare segnaposto durante il caricamento delle immagini in un thread in background. –

2

È possibile utilizzare Directory.EnumerateFiles insieme a Parallel.ForEach per distribuire il lavoro su tutte le CPU disponibili.

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

Che presume che stia usando .NET4.0 –

0

probabilmente non può accelerare le cose come il collo di bottiglia è la lettura dei file stessi dal disco e forse loro analisi come immagini.

Quello che puoi fare è Cache l'elenco dopo che è stato caricato e tutte le chiamate successive al tuo codice saranno molto più veloci.