Skip to content

Image.Load and Image.LoadAsync is slow for network shares #1276

@TedStryker

Description

@TedStryker

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

System Configuration

  • ImageSharp version: repo pulled yesterday, build with release config with VS2019 Preview 3.1
  • Environment (Operating system, version and so on): Win 8.1
  • .NET Framework version: Core 3.1.400 (from VS2019 Preview 3.1)

@pekspro
I changed my code to use your new LoadAsync overload tosurprisingly find, that your's is noticeably slower.
When loading & resizing 2 random pictures (SaveAsync vs. SaveAsJpeg makes no difference), here is my "manual" benchmark (average after 30 executions):
Mine/Yours (ms):
300/550
180/300

I'm not so much into async I/O, so I have no explanation, but perhaps you have one and are able to further optimize this beautiful library.
I ignored initial file loading from disk, so what the benchmarks show is probably loading from Windows filesystem cache.

The environment is a ASP.NET Core MVC app.
The calls:
// My implementation: return File(await image.LoadFromDisk(requestDimensions), "image/jpeg", $"{image.Name}-{requestDimensions}.jpg");

// Yours: return File(await image.LoadFromDiskAsync(requestDimensions), "image/jpeg", $"{image.Name}-{requestDimensions}.jpg");

The code:
-Integration of your overload:

var outputStream = new MemoryStream();
using (var image = await Image.LoadAsync(Configuration.Default, Url, Config.JpegDecoder)) {               
		image.Mutate(i => i.Resize(new ResizeOptions {
			Size = new Size(requestedDimensions[0], requestedDimensions[1]),
			Mode = ResizeMode.BoxPad,
			Sampler = Config.ImageResampler,
		}));               

await image.SaveAsync(outputStream, Config.ImageJpegEncoder);
outputStream.Seek(0, SeekOrigin.Begin);

-Mine:

await using var fs = File.OpenRead(Url);
var result = new byte[fs.Length];
await fs.ReadAsync(result, 0, (int)fs.Length);

using var image = Image.Load<Rgba32>(result, Config.JpegDecoder);
image.Mutate(i => i.Resize(new ResizeOptions { /* same as above*/ }));

var outputStream = new MemoryStream();
image.SaveAsJpeg(outputStream, Config.ImageJpegEncoder);
outputStream.Seek(0, SeekOrigin.Begin);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions