Speeding up the loading of a List of images
Asked Answered
S

6

6

I'm loading a List<Image> from a folder of about 250 images. I did a DateTime comparison and it takes a full 11 second to load those 250 images. That's slow as hell, and I'd very much like to speed that up.

The images are on my local harddrive, not even an external one.

The code:

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: yes, I need all the pictures. The thing I'm planning is to take the center 30 pixelcolums of each and make a new image out of that. Kinda like a 360 degrees picture. Only right now, I'm just testing with random images.

I know there are probably way better frameworks out there to do this, but I need this to work first.

EDIT2: Switched to a stopwatch, the difference is just a few milliseconds. Also tried it with Directory.EnumerateFiles, but no difference at all.

EDIT3: I am running .NET 4, on a 32-bit Win7 client.

Synthetic answered 28/10, 2010 at 20:25 Comment(4)
I'm not even going to look at the code yet. Whenever doing performance benchmarks, don't use DateTime! Use a Stopwatch object instead. They're much more accurate and reliable.Preciousprecipice
I would generally use a Stopwatch to do the timing. Found in system.diagnostics.Geilich
Kind of tangential to your question but for timing how long operations take in your code system.diagnostics.stopwatch works a lot better.Haulm
@Justin Niessner: For an operation taking 11 seconds, it doesn't matter.Luxor
B
1

As loading a image does both file IO and CPU work, you should get some speadup by using more then one thread.

If you are using .net 4, using tasks would be the way to go.

Byline answered 28/10, 2010 at 20:29 Comment(0)
L
3

Do you actually need to load all the images? Can you get away with loading them lazily? Alternatively, can you load them on a separate thread?

Luxor answered 28/10, 2010 at 20:28 Comment(0)
T
2

You cannot speed up your HDD access and decoding speed. However a good idea would be to load the images in a background thread.

Perhaps you should consider showing a placeholder until the image is actually loaded.

Caution: you'll need to insert the loaded images in your UI thread anyway!

Theocentric answered 28/10, 2010 at 20:29 Comment(4)
Well, that's not completely true. He could replace it with an SSD.Luxor
@Jason: I meant, programmatically :-DTheocentric
+1 for the suggestion to show place holder while loading images in a background thread.Glottal
@WebDevHobo: loadbar would be more complicated, as it must report loading progress (which is not a trivial thing). Just a preloaded generic image which can be visually distinguished from the "valid" images. (It can contain "Loading...", for example.)Theocentric
P
2

You could use Directory.EnumerateFiles along with Parallel.ForEach to spread the work over as many CPUs as you have.

var directory = "C:\\foo";
var files = Directory.EnumerateFiles(directory, "*.jpg");
var images = files.AsParallel().Select(file => Image.FromFile(file)).ToList();
Pasha answered 28/10, 2010 at 20:34 Comment(1)
That assumes he is using .NET4.0Teador
B
1

As loading a image does both file IO and CPU work, you should get some speadup by using more then one thread.

If you are using .net 4, using tasks would be the way to go.

Byline answered 28/10, 2010 at 20:29 Comment(0)
V
1

Given that you likely already know the path (from the dialog box?), you might be better using Directory.EnumerateFiles and then work with the collection it returns instead of a list.

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

[edit]

just noticed you're also loading the files into your app within the loop - how big are they? Depending on their size, it might actually be a pretty good speed!

Do you need to load them at this point? Can you change some display code elsewhere to load on demand?

Valence answered 28/10, 2010 at 20:29 Comment(1)
I tried it, but there is no speed difference. I also changed to a stopwatch, the difference is but a few milliseconds.Synthetic
R
0

You probably can't speed things up as the bottle neck is reading the files themselves from disk and maybe parsing them as images.

What you can do though is Cache the list after it's loaded and then any subsequent calls to your code will be lot faster.

Ranie answered 28/10, 2010 at 21:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.