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.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@ -9,6 +10,7 @@ using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using ImageMagick;
using PhotoSauce.MagicScaler;
@ -124,6 +126,32 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave
new ParallelOptions { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism },
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)
{
this.LastProcessedImageSize = new Size(width, height);
@ -197,6 +225,26 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave
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)
{
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}");
Stopwatch timer;
if (options == null || !options.ImageSharp)
if (options == null || !(options.ImageSharp || options.AsyncImageSharp))
{
RunBenchmarkSwitcher(lrs, out timer);
}
@ -74,7 +74,16 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
{
for (int i = 0; i < options.RepeatCount; i++)
{
lrs.ImageSharpBenchmarkParallel();
if (options.AsyncImageSharp)
{
lrs.ImageSharpBenchmarkParallelAsync();
}
else
{
lrs.ImageSharpBenchmarkParallel();
}
Console.WriteLine("OK");
}
}
catch (Exception ex)
@ -221,6 +230,9 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
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")]
public bool ImageSharp { get; set; }
@ -277,7 +289,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox
}
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()
{
@ -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 MagicScalerBenchmarkParallel() => this.ForEachImage(this.Benchmarks.MagicScalerResize);
private void SkiaBitmapBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapResize);
private void SkiaBitmapDecodeToTargetSizeBenchmarkParallel() => this.ForEachImage(this.Benchmarks.SkiaBitmapDecodeToTargetSize);
private void NetVipsBenchmarkParallel() => this.ForEachImage(this.Benchmarks.NetVipsResize);

Loading…
Cancel
Save