views:

86

answers:

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.

+3  A: 

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?

Jason
+1  A: 

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.

Ian Ringrose
+1  A: 

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?

dotalchemy
I tried it, but there is no speed difference. I also changed to a stopwatch, the difference is but a few milliseconds.
WebDevHobo
+2  A: 

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!

Vlad
Well, that's not completely true. He could replace it with an SSD.
Jason
@Jason: I meant, programmatically :-D
Vlad
+1 for the suggestion to show place holder while loading images in a background thread.
Chris Taylor
Placeholder, like a loadbar?
WebDevHobo
@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.)
Vlad
+2  A: 

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();
Jake Pearson
That assumes he is using .NET4.0
Foovanadil
A: 

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.

Shadow Wizard