Browse Source

AsyncImageSharp option for load testing

pull/2006/head
Anton Firszov 4 years ago
committed by Dan Kroymann
parent
commit
faea7d05db
  1. 48
      tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs
  2. 24
      tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs

48
tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
@ -9,6 +10,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ImageMagick; using ImageMagick;
using PhotoSauce.MagicScaler; using PhotoSauce.MagicScaler;
@ -124,6 +126,32 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave
new ParallelOptions { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism }, new ParallelOptions { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism },
action); action);
public Task ForEachImageParallelAsync(Func<string, Task> action)
{
int maxDegreeOfParallelism = this.MaxDegreeOfParallelism > 0
? this.MaxDegreeOfParallelism
: Environment.ProcessorCount;
int partitionSize = (int)Math.Ceiling((double)this.Images.Length / maxDegreeOfParallelism);
List<Task> tasks = new();
for (int i = 0; i < this.Images.Length; i += partitionSize)
{
int end = Math.Min(i + partitionSize, this.Images.Length);
Task task = RunPartition(i, end);
tasks.Add(task);
}
return Task.WhenAll(tasks);
Task RunPartition(int start, int end) => Task.Run(async () =>
{
for (int i = start; i < end; i++)
{
await action(this.Images[i]);
}
});
}
private void LogImageProcessed(int width, int height) private void LogImageProcessed(int width, int height)
{ {
this.LastProcessedImageSize = new Size(width, height); this.LastProcessedImageSize = new Size(width, height);
@ -197,6 +225,26 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave
image.Save(output, this.imageSharpJpegEncoder); image.Save(output, this.imageSharpJpegEncoder);
} }
public async Task ImageSharpResizeAsync(string input)
{
using FileStream output = File.Open(this.OutputPath(input), FileMode.Create);
// Resize it to fit a 150x150 square
using var image = await ImageSharpImage.LoadAsync(input);
this.LogImageProcessed(image.Width, image.Height);
image.Mutate(i => i.Resize(new ResizeOptions
{
Size = new ImageSharpSize(this.ThumbnailSize, this.ThumbnailSize),
Mode = ResizeMode.Max
}));
// Reduce the size of the file
image.Metadata.ExifProfile = null;
// Save the results
await image.SaveAsync(output, this.imageSharpJpegEncoder);
}
public void MagickResize(string input) public void MagickResize(string input)
{ {
using var image = new MagickImage(input); using var image = new MagickImage(input);

24
tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs

@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
Console.WriteLine($"\nEnvironment.ProcessorCount={Environment.ProcessorCount}"); Console.WriteLine($"\nEnvironment.ProcessorCount={Environment.ProcessorCount}");
Stopwatch timer; Stopwatch timer;
if (options == null || !options.ImageSharp) if (options == null || !(options.ImageSharp || options.AsyncImageSharp))
{ {
RunBenchmarkSwitcher(lrs, out timer); RunBenchmarkSwitcher(lrs, out timer);
} }
@ -74,7 +74,16 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
{ {
for (int i = 0; i < options.RepeatCount; i++) for (int i = 0; i < options.RepeatCount; i++)
{ {
lrs.ImageSharpBenchmarkParallel(); if (options.AsyncImageSharp)
{
lrs.ImageSharpBenchmarkParallelAsync();
}
else
{
lrs.ImageSharpBenchmarkParallel();
}
Console.WriteLine("OK");
} }
} }
catch (Exception ex) catch (Exception ex)
@ -221,6 +230,9 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
private class CommandLineOptions private class CommandLineOptions
{ {
[Option('a', "async-imagesharp", Required = false, Default = false, HelpText = "Async ImageSharp without benchmark switching")]
public bool AsyncImageSharp { get; set; }
[Option('i', "imagesharp", Required = false, Default = false, HelpText = "Test ImageSharp without benchmark switching")] [Option('i', "imagesharp", Required = false, Default = false, HelpText = "Test ImageSharp without benchmark switching")]
public bool ImageSharp { get; set; } public bool ImageSharp { get; set; }
@ -277,7 +289,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
} }
public override string ToString() => public override string ToString() =>
$"p({this.MaxDegreeOfParallelism})_i({this.ImageSharp})_d({this.KeepDefaultAllocator})_m({this.MaxContiguousPoolBufferMegaBytes})_s({this.MaxPoolSizeMegaBytes})_u({this.MaxCapacityOfNonPoolBuffersMegaBytes})_r({this.RepeatCount})_g({this.GcFrequency})_e({this.ReleaseRetainedResourcesAtEnd})_l({this.LeakFrequency})"; $"p({this.MaxDegreeOfParallelism})_i({this.ImageSharp})_a({this.AsyncImageSharp})_d({this.KeepDefaultAllocator})_m({this.MaxContiguousPoolBufferMegaBytes})_s({this.MaxPoolSizeMegaBytes})_u({this.MaxCapacityOfNonPoolBuffersMegaBytes})_r({this.RepeatCount})_g({this.GcFrequency})_e({this.ReleaseRetainedResourcesAtEnd})_l({this.LeakFrequency})";
public MemoryAllocator CreateMemoryAllocator() public MemoryAllocator CreateMemoryAllocator()
{ {
@ -330,11 +342,17 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
} }
}); });
private void ImageSharpBenchmarkParallelAsync() =>
this.Benchmarks.ForEachImageParallelAsync(f => this.Benchmarks.ImageSharpResizeAsync(f))
.GetAwaiter()
.GetResult();
private void MagickBenchmarkParallel() => this.ForEachImage(this.Benchmarks.MagickResize); private void MagickBenchmarkParallel() => this.ForEachImage(this.Benchmarks.MagickResize);
private void MagicScalerBenchmarkParallel() => this.ForEachImage(this.Benchmarks.MagicScalerResize); private void MagicScalerBenchmarkParallel() => this.ForEachImage(this.Benchmarks.MagicScalerResize);
private void SkiaBitmapBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapResize); private void SkiaBitmapBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapResize);
private void SkiaBitmapDecodeToTargetSizeBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapDecodeToTargetSize); private void SkiaBitmapDecodeToTargetSizeBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapDecodeToTargetSize);
private void NetVipsBenchmarkParallel() => this.ForEachImage(this.Benchmarks.NetVipsResize); private void NetVipsBenchmarkParallel() => this.ForEachImage(this.Benchmarks.NetVipsResize);

Loading…
Cancel
Save