Resizing photos on a multicore environment

What is it?

A while ago I created a simple application to reduce the size of images as I wanted more and more of them stored on my mobile phone
https://timdows.com/projects/resizing-photos-to-have-them-all-on-your-32gb-storage-phone/

Using this application again, I wanted it to be running in dotnet core, but the System.Drawing library is not yet available on the dotnet core environments. The solution was using ImageSharp from SixLabors, it runs with dotnet core and has the two options I require, i.e. resizing and changing the orientation if needed.

The code that does this magic for us is just one line:

image.Mutate(x => x.Resize(newWidth, newHeight).AutoOrient());

The code

All the code can be found on my github: https://github.com/timdows/ImageResizer

It takes three arguments:

  • Input directory
  • Save directory
  • MaxSize of the image

It iterates over all the images and creates a task for every image to be scaled.
Next, these tasks are executed in parallel.

Some background information about tasks vs threads that I always find helpful can be found here

Statistics without tasks

Lets measure the time it takes to complete my set of photo’s, in this case 1054 images with a total size of 2.7GB

When we run it with no tasks, i.e. run everything concurrent, it takes 392984 ms to complete my set of photo’s and my CPU utilization looks like this:

Statistics with tasks

The next runs creates a list of tasks, every image to be scaled is added to this list. Next the list of tasks is executed with the following code:

await Task.WhenAll(backgroundTasks);

Setting the number of worker threads can influence the time it takes to complete the set of photo’s, but I didn’t noticed this during my runs though (modifying it made it even worse in my tests), and my CPU utilization during execution looks like this:

Number of workerThreadsTime in ms to complete
Unset244632
4 (the minimum number on my machine)
246549
8
252431
16263300

Conclusion

Going from 390 seconds if no tasks are used, my machine responds a bit better (d0h, not all CPU resources are occupied by the scaling process), to a 240 seconds executing time is a 40% reduction!

But sometimes you want things to be done quickly and don’t care if your machine responds a bit slower. Using tasks is the way to go!