From 5404eb6bb150c34f8ef92c84b316d7ad8a2db60b Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Nov 2018 01:53:21 +0100 Subject: [PATCH] improved benchmarks + more benchmark results --- .../Common/Helpers/InliningOptions.cs | 2 +- .../Codecs/Jpeg/DecodeJpeg.cs | 89 ------------- .../Codecs/Jpeg/DecodeJpegMultiple.cs | 18 ++- .../Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs | 125 ++++++++++++++++++ .../Codecs/Jpeg/LoadResizeSave.cs | 2 +- .../Codecs/Jpeg/LoadResizeSave_MultiImage.cs | 88 ++++++++++++ .../Codecs/MultiImageBenchmarkBase.cs | 30 ++++- .../ProfilingBenchmarks/JpegBenchmarks.cs | 56 ++++---- tests/ImageSharp.Tests/TestImages.cs | 13 ++ 9 files changed, 294 insertions(+), 129 deletions(-) delete mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs create mode 100644 tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index ad85c4fc8..069a426d7 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -// Uncomment this for verbose profiler results: +// Uncomment this for verbose profiler results. DO NOT PUSH TO MAIN! // #define PROFILING using System.Runtime.CompilerServices; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs deleted file mode 100644 index 57dcede88..000000000 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System.Drawing; -using System.IO; -using BenchmarkDotNet.Attributes; - -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests; -using CoreSize = SixLabors.Primitives.Size; -using SDImage = System.Drawing.Image; - -namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg -{ - [Config(typeof(Config.ShortClr))] - public class DecodeJpeg - { - private byte[] jpegBytes; - - private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - - [Params(TestImages.Jpeg.Baseline.Jpeg420Exif - //, TestImages.Jpeg.Baseline.Calliphora - )] - public string TestImage { get; set; } - - [GlobalSetup] - public void ReadImages() - { - if (this.jpegBytes == null) - { - this.jpegBytes = File.ReadAllBytes(this.TestImageFullPath); - } - } - - [Benchmark(Baseline = true, Description = "Decode Jpeg - System.Drawing")] - public Size JpegSystemDrawing() - { - using (var memoryStream = new MemoryStream(this.jpegBytes)) - { - using (var image = SDImage.FromStream(memoryStream)) - { - return image.Size; - } - } - } - - [Benchmark(Description = "Decode Jpeg - ImageSharp")] - public CoreSize JpegImageSharp() - { - using (var memoryStream = new MemoryStream(this.jpegBytes)) - { - using (var image = Image.Load(memoryStream, new JpegDecoder())) - { - return new CoreSize(image.Width, image.Height); - } - } - } - - // RESULTS (2018 October): - // - // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 - // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores - // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC - // .NET Core SDK=2.1.403 - // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // - // - // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| - // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | - // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | - // | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | - - // RESULTS (2018 November 1): - // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | - // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| - // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.59 ms | 4.611 ms | 0.2605 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | - // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 55.33 ms | 2.133 ms | 0.1205 ms | 3.15 | 0.04 | 125.0000 | 566.01 KB | - // | | | | | | | | | | - // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.83 ms | 24.326 ms | 1.3745 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | - // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 44.93 ms | 3.088 ms | 0.1745 ms | 2.53 | 0.15 | 125.0000 | 529.96 KB | - } -} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs index be0fe76b8..53459e3c4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs @@ -2,23 +2,27 @@ // Licensed under the Apache License, Version 2.0. using System.Collections.Generic; + using BenchmarkDotNet.Attributes; + using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + using SDImage = System.Drawing.Image; namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { - [Config(typeof(Config.ShortClr))] + /// + /// An expensive Jpeg benchmark, running on a wide range of input images, showing aggregate results. + /// + [Config(typeof(MultiImageBenchmarkBase.Config))] public class DecodeJpegMultiple : MultiImageBenchmarkBase { - protected override IEnumerable InputImageSubfoldersOrFiles => new[] - { - "Jpg/baseline", - "Jpg/progressive", - }; + protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; - protected override IEnumerable SearchPatterns => new[] { "*.jpg" }; + [Params(InputImageCategory.AllImages)] + public override InputImageCategory InputCategory { get; set; } [Benchmark(Description = "DecodeJpegMultiple - ImageSharp")] public void DecodeJpegImageSharp() diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs new file mode 100644 index 000000000..e161bca05 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -0,0 +1,125 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Drawing; +using System.IO; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; + +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; +using CoreSize = SixLabors.Primitives.Size; +using SDImage = System.Drawing.Image; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + /// + /// Image-specific Jpeg benchmarks + /// + [Config(typeof(Config.ShortClr))] + public class DecodeJpeg_ImageSpecific + { + public class Config : ManualConfig + { + public Config() + { + // Uncomment if you want to use any of the diagnoser + this.Add(new BenchmarkDotNet.Diagnosers.MemoryDiagnoser()); + } + + public class ShortClr : Benchmarks.Config + { + public ShortClr() + { + this.Add( + //Job.Clr.WithLaunchCount(1).WithWarmupCount(2).WithTargetCount(3), + Job.Core.WithLaunchCount(1).WithWarmupCount(2).WithTargetCount(3) + ); + } + } + } + + private byte[] jpegBytes; + + private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [Params( + TestImages.Jpeg.Baseline.Lake, + TestImages.Jpeg.Issues.BadRstProgressive518, + TestImages.Jpeg.Issues.ExifGetString750Transform, + + TestImages.Jpeg.Baseline.Jpeg420Exif + )] + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.jpegBytes == null) + { + this.jpegBytes = File.ReadAllBytes(this.TestImageFullPath); + } + } + + [Benchmark(Baseline = true, Description = "Decode Jpeg - System.Drawing")] + public Size JpegSystemDrawing() + { + using (var memoryStream = new MemoryStream(this.jpegBytes)) + { + using (var image = SDImage.FromStream(memoryStream)) + { + return image.Size; + } + } + } + + [Benchmark(Description = "Decode Jpeg - ImageSharp")] + public CoreSize JpegImageSharp() + { + using (var memoryStream = new MemoryStream(this.jpegBytes)) + { + using (var image = Image.Load(memoryStream, new JpegDecoder(){ IgnoreMetadata = true})) + { + return new CoreSize(image.Width, image.Height); + } + } + } + + // RESULTS (2018 October 31): + // + // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC + // .NET Core SDK=2.1.403 + // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // Job-MCUBGX : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 + // Job-TZIRPF : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT + // + // + // Method | Runtime | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated | + // ------------------------------- |-------- |----------------------------- |---------:|----------:|----------:|-------:|---------:|---------:|----------:| + // 'Decode Jpeg - System.Drawing' | Clr | Jpg/baseline/jpeg420exif.jpg | 17.10 ms | 4.720 ms | 0.2667 ms | 1.00 | 0.00 | 218.7500 | 757.88 KB | + // 'Decode Jpeg - ImageSharp' | Clr | Jpg/baseline/jpeg420exif.jpg | 57.77 ms | 4.626 ms | 0.2614 ms | 3.38 | 0.04 | 125.0000 | 566.01 KB | + // | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Core | Jpg/baseline/jpeg420exif.jpg | 17.45 ms | 2.092 ms | 0.1182 ms | 1.00 | 0.00 | 218.7500 | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Core | Jpg/baseline/jpeg420exif.jpg | 48.39 ms | 14.562 ms | 0.8228 ms | 2.77 | 0.04 | 125.0000 | 529.96 KB | + + // RESULTS (2018 November 4): + // Method | TestImage | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Gen 1 | Gen 2 | Allocated | + // ------------------------------- |-------------------------------------------- |-----------:|-----------:|----------:|-------:|---------:|----------:|---------:|---------:|------------:| + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/Lake.jpg | 6.291 ms | 1.200 ms | 0.0678 ms | 1.00 | 0.00 | 62.5000 | - | - | 205.83 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/Lake.jpg | 18.493 ms | 3.025 ms | 0.1709 ms | 2.94 | 0.03 | - | - | - | 19.97 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/baseline/jpeg420exif.jpg | 16.962 ms | 1.446 ms | 0.0817 ms | 1.00 | 0.00 | 218.7500 | - | - | 757.04 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/baseline/jpeg420exif.jpg | 42.105 ms | 4.496 ms | 0.2540 ms | 2.48 | 0.02 | - | - | - | 21.94 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 432.344 ms | 89.746 ms | 5.0708 ms | 1.00 | 0.00 | 2375.0000 | - | - | 7403.76 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/Issue518-Bad-RST-Progressive.jpg | 421.292 ms | 128.587 ms | 7.2654 ms | 0.97 | 0.02 | 125.0000 | 125.0000 | 125.0000 | 35186.98 KB | + // | | | | | | | | | | | + // 'Decode Jpeg - System.Drawing' | Jpg/issues/issue750-exif-tranform.jpg | 94.723 ms | 4.663 ms | 0.2635 ms | 1.00 | 0.00 | 1750.0000 | - | - | 5492.63 KB | + // 'Decode Jpeg - ImageSharp' | Jpg/issues/issue750-exif-tranform.jpg | 234.071 ms | 37.979 ms | 2.1459 ms | 2.47 | 0.02 | 312.5000 | 312.5000 | 312.5000 | 58834.45 KB | + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs index 72062fc7d..b6a4711c4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave.cs @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - // RESULTS (2018 October): + // RESULTS (2018 October 31): // // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs new file mode 100644 index 000000000..111c509cf --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/LoadResizeSave_MultiImage.cs @@ -0,0 +1,88 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; + +using BenchmarkDotNet.Attributes; + +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Tests; +// ReSharper disable InconsistentNaming + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + [Config(typeof(MultiImageBenchmarkBase.Config))] + public class LoadResizeSave_MultiImage : MultiImageBenchmarkBase + { + protected override IEnumerable InputImageSubfoldersOrFiles => TestImages.Jpeg.BenchmarkSuite; + + [Params(InputImageCategory.AllImages)] + public override InputImageCategory InputCategory { get; set; } + + private readonly Configuration configuration = new Configuration(new JpegConfigurationModule()); + + private byte[] destBytes; + + public override void Setup() + { + base.Setup(); + + this.configuration.MaxDegreeOfParallelism = 1; + const int MaxOutputSizeInBytes = 2 * 1024 * 1024; // ~2 MB + this.destBytes = new byte[MaxOutputSizeInBytes]; + } + + [Benchmark(Baseline = true)] + public void SystemDrawing() + { + this.ForEachStream( + sourceStream => + { + using (var destStream = new MemoryStream(this.destBytes)) + using (var source = System.Drawing.Image.FromStream(sourceStream)) + using (var destination = new Bitmap(source.Width / 4, source.Height / 4)) + { + using (var g = Graphics.FromImage(destination)) + { + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.CompositingQuality = CompositingQuality.HighQuality; + g.DrawImage(source, 0, 0, 400, 400); + } + + destination.Save(destStream, ImageFormat.Jpeg); + } + + return null; + }); + } + + [Benchmark] + public void ImageSharp() + { + this.ForEachStream( + sourceStream => + { + using (var source = Image.Load( + this.configuration, + sourceStream, + new JpegDecoder { IgnoreMetadata = true })) + { + using (var destStream = new MemoryStream(this.destBytes)) + { + source.Mutate(c => c.Resize(source.Width / 4, source.Height / 4)); + source.SaveAsJpeg(destStream); + } + } + + return null; + }); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs index 608d3604f..446c03859 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs @@ -3,6 +3,9 @@ // Licensed under the Apache License, Version 2.0. // +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; + using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.Codecs @@ -22,6 +25,25 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public abstract class MultiImageBenchmarkBase { + public class Config : ManualConfig + { + public Config() + { + // Uncomment if you want to use any of the diagnoser + this.Add(new BenchmarkDotNet.Diagnosers.MemoryDiagnoser()); + } + + public class ShortClr : Benchmarks.Config + { + public ShortClr() + { + this.Add( + Job.Core.WithLaunchCount(1).WithWarmupCount(1).WithTargetCount(2) + ); + } + } + } + protected Dictionary FileNamesToBytes = new Dictionary(); protected Dictionary> FileNamesToImageSharpImages = new Dictionary>(); @@ -49,7 +71,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs /// /// Gets the file names containing these strings are substrings are not processed by the benchmark. /// - protected IEnumerable ExcludeSubstringsInFileNames => new[] { "badeof", "BadEof", "CriticalEOF" }; + protected virtual IEnumerable ExcludeSubstringsInFileNames => new[] { "badeof", "BadEof", "CriticalEOF" }; /// /// Enumerates folders containing files OR files to be processed by the benchmark. @@ -87,7 +109,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs protected abstract IEnumerable InputImageSubfoldersOrFiles { get; } [GlobalSetup] - public void ReadImages() + public virtual void Setup() { if (!Vector.IsHardwareAccelerated) { @@ -107,11 +129,13 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs continue; } + string[] excludeStrings = this.ExcludeSubstringsInFileNames.Select(s => s.ToLower()).ToArray(); + string[] allFiles = this.SearchPatterns.SelectMany( f => Directory.EnumerateFiles(path, f, SearchOption.AllDirectories) - .Where(fn => !this.ExcludeSubstringsInFileNames.Any(w => fn.ToLower().Contains(w)))).ToArray(); + .Where(fn => !excludeStrings.Any(excludeStr => fn.ToLower().Contains(excludeStr)))).ToArray(); foreach (string fn in allFiles) { diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs index 3d439c5ce..a7f848e3a 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegBenchmarks.cs @@ -22,15 +22,19 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { } - public static readonly TheoryData DecodeJpegData = new TheoryData() - { - //TestImages.Jpeg.Baseline.Cmyk, - //TestImages.Jpeg.Baseline.Ycck, - TestImages.Jpeg.Baseline.Calliphora, - TestImages.Jpeg.Baseline.Jpeg400, - TestImages.Jpeg.Baseline.Jpeg420Exif, - TestImages.Jpeg.Baseline.Jpeg444, - }; + public static readonly TheoryData DecodeJpegData = new TheoryData + { + // Except "Jpeg400", all images are YCbCr + + TestImages.Jpeg.Baseline.Jpeg400, + TestImages.Jpeg.Baseline.Jpeg420Exif, + TestImages.Jpeg.Baseline.Lake, // 444 + + // Using images from the "issues" set, because they are LARGE + TestImages.Jpeg.Issues.MissingFF00ProgressiveBedroom159, // 420 + TestImages.Jpeg.Issues.BadRstProgressive518, // 444 + TestImages.Jpeg.Issues.ExifGetString750Transform, // 420 + }; [Theory(Skip = ProfilingSetup.SkipProfilingTests)] [MemberData(nameof(DecodeJpegData))] @@ -38,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { this.DecodeJpegBenchmarkImpl(fileName, new JpegDecoder()); } - + private void DecodeJpegBenchmarkImpl(string fileName, IImageDecoder decoder) { // do not run this on CI even by accident @@ -47,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks return; } - const int ExecutionCount = 30; + const int ExecutionCount = 10; if (!Vector.IsHardwareAccelerated) { @@ -83,29 +87,26 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks } string[] testFiles = TestImages.Bmp.All - .Concat(new[] { TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk }) - .ToArray(); + .Concat(new[] { TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk }).ToArray(); - Image[] testImages = - testFiles.Select( - tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.Rgba32).GetImage()) - .ToArray(); + Image[] testImages = testFiles.Select( + tf => TestImageProvider.File(tf, pixelTypeOverride: PixelTypes.Rgba32).GetImage()).ToArray(); using (var ms = new MemoryStream()) { - this.Measure(executionCount, + this.Measure( + executionCount, () => - { - foreach (Image img in testImages) { - var options = new JpegEncoder { Quality = quality, Subsample = subsample }; - img.Save(ms, options); - ms.Seek(0, SeekOrigin.Begin); - } - }, + foreach (Image img in testImages) + { + var options = new JpegEncoder { Quality = quality, Subsample = subsample }; + img.Save(ms, options); + ms.Seek(0, SeekOrigin.Begin); + } + }, // ReSharper disable once ExplicitCallerInfoArgument - $@"Encode {testFiles.Length} images" - ); + $@"Encode {testFiles.Length} images"); } foreach (Image image in testImages) @@ -113,6 +114,5 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks image.Dispose(); } } - } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 03f875485..caffe81ab 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -165,6 +165,19 @@ namespace SixLabors.ImageSharp.Tests } public static readonly string[] All = Baseline.All.Concat(Progressive.All).ToArray(); + + public static readonly string[] BenchmarkSuite = + { + // Except "Jpeg400", all images are YCbCr + Baseline.Jpeg400, + Baseline.Jpeg420Exif, + Baseline.Lake, // 444 + + // Using images from the "issues" set, because they are LARGE + Issues.MissingFF00ProgressiveBedroom159, // 420 + Issues.BadRstProgressive518, // 444 + Issues.ExifGetString750Transform, // 420 + }; } public static class Bmp