Browse Source

Speed up tga decoding and add new benchmark comparison

af/merge-core
James Jackson-South 6 years ago
parent
commit
26fc9b3906
  1. 7
      Directory.Build.targets
  2. 2
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  3. 14
      src/ImageSharp/Image.FromBytes.cs
  4. 67
      tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs
  5. 5
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs
  6. 3
      tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs
  7. 9
      tests/ImageSharp.Benchmarks/Config.cs
  8. 3
      tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

7
Directory.Build.targets

@ -22,18 +22,19 @@
<!-- Package versions for package references across all projects -->
<ItemGroup>
<PackageReference Update="BenchmarkDotNet" Version="0.11.5" />
<PackageReference Update="Colourful" Version="2.0.2" />
<PackageReference Update="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Update="Colourful" Version="2.0.3" />
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="7.14.4" />
<PackageReference Update="Microsoft.Net.Compilers.Toolset" Version="3.3.1" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Update="Moq" Version="4.10.0" />
<PackageReference Update="Pfim" Version="0.9.1" />
<PackageReference Update="SixLabors.Core" Version="1.0.0-beta0008" />
<PackageReference Update="SixLabors.Fonts" Version="1.0.0-beta0009" />
<PackageReference Update="SixLabors.Shapes" Version="1.0.0-beta0009" />
<PackageReference Update="SixLabors.Shapes.Text" Version="1.0.0-beta0009" />
<PackageReference Update="StyleCop.Analyzers" Version="1.1.118" />
<PackageReference Update="System.Drawing.Common" Version="4.5.1" />
<PackageReference Update="System.Drawing.Common" Version="4.7.0" />
<PackageReference Update="System.IO.Compression" Version="4.3.0" />
<PackageReference Update="System.IO.UnmanagedMemoryStream" Version="4.3.0" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" />

2
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
throw new UnknownImageFormatException("Width or height cannot be 0");
}
var image = new Image<TPixel>(this.configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata);
var image = Image.CreateUninitialized<TPixel>(this.configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata);
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
if (this.fileHeader.ColorMapType is 1)

14
src/ImageSharp/Image.FromBytes.cs

@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data)
where TPixel : struct, IPixel<TPixel>
{
using (var stream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, stream);
}
@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data, out IImageFormat format)
where TPixel : struct, IPixel<TPixel>
{
using (var stream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, stream, out format);
}
@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp
public static Image<TPixel> Load<TPixel>(byte[] data, IImageDecoder decoder)
where TPixel : struct, IPixel<TPixel>
{
using (var stream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(stream, decoder);
}
@ -125,9 +125,9 @@ namespace SixLabors.ImageSharp
public static Image<TPixel> Load<TPixel>(Configuration config, byte[] data, IImageDecoder decoder)
where TPixel : struct, IPixel<TPixel>
{
using (var memoryStream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(config, memoryStream, decoder);
return Load<TPixel>(config, stream, decoder);
}
}
@ -299,7 +299,7 @@ namespace SixLabors.ImageSharp
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, byte[] data, IImageDecoder decoder)
{
using (var stream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load(config, stream, decoder);
}
@ -314,7 +314,7 @@ namespace SixLabors.ImageSharp
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration config, byte[] data, out IImageFormat format)
{
using (var stream = new MemoryStream(data))
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load(config, stream, out format);
}

67
tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs

@ -1,15 +1,16 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Buffers;
using System.IO;
using System.Threading;
using BenchmarkDotNet.Attributes;
using ImageMagick;
using Pfim;
using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Benchmarks.Codecs
{
@ -17,26 +18,74 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
public class DecodeTga : BenchmarkBase
{
private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage);
private readonly PfimConfig pfimConfig = new PfimConfig(allocator: new PfimAllocator());
private byte[] data;
[Params(TestImages.Tga.Bit24)]
public string TestImage { get; set; }
[GlobalSetup]
public void SetupData()
{
this.data = File.ReadAllBytes(this.TestImageFullPath);
}
[Benchmark(Baseline = true, Description = "ImageMagick Tga")]
public Size TgaImageMagick()
public int TgaImageMagick()
{
using (var magickImage = new MagickImage(this.TestImageFullPath))
var settings = new MagickReadSettings { Format = MagickFormat.Tga };
using (var image = new MagickImage(new MemoryStream(this.data), settings))
{
return new Size(magickImage.Width, magickImage.Height);
return image.Width;
}
}
[Benchmark(Description = "ImageSharp Tga")]
public Size TgaCore()
public int TgaCore()
{
using (var image = Image.Load<Rgba32>(this.TestImageFullPath))
using (var image = Image.Load<Bgr24>(this.data, new TgaDecoder()))
{
return new Size(image.Width, image.Height);
return image.Width;
}
}
[Benchmark(Description = "Pfim Tga")]
public int TgaPfim()
{
using (var image = Targa.Create(this.data, this.pfimConfig))
{
return image.Width;
}
}
private class PfimAllocator : IImageAllocator
{
private int rented;
private readonly ArrayPool<byte> shared = ArrayPool<byte>.Shared;
public byte[] Rent(int size)
{
return this.shared.Rent(size);
}
public void Return(byte[] data)
{
Interlocked.Decrement(ref this.rented);
this.shared.Return(data);
}
public int Rented => this.rented;
}
// RESULTS (07/01/2020)
//| Method | Runtime | TestImage | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated |
//|------------------ |-------------- |-------------------- |-------------:|-------------:|-----------:|------:|-------:|------:|------:|----------:|
//| 'ImageMagick Tga' | .NET 4.7.2 | Tga/targa_24bit.tga | 1,778.965 us | 1,711.088 us | 93.7905 us | 1.000 | 1.9531 | - | - | 13668 B |
//| 'ImageSharp Tga' | .NET 4.7.2 | Tga/targa_24bit.tga | 38.659 us | 6.886 us | 0.3774 us | 0.022 | 0.3052 | - | - | 1316 B |
//| 'Pfim Tga' | .NET 4.7.2 | Tga/targa_24bit.tga | 6.752 us | 10.268 us | 0.5628 us | 0.004 | 0.0687 | - | - | 313 B |
//| | | | | | | | | | | |
//| 'ImageMagick Tga' | .NET Core 2.1 | Tga/targa_24bit.tga | 1,407.585 us | 124.215 us | 6.8087 us | 1.000 | 1.9531 | - | - | 13307 B |
//| 'ImageSharp Tga' | .NET Core 2.1 | Tga/targa_24bit.tga | 17.958 us | 9.352 us | 0.5126 us | 0.013 | 0.2747 | - | - | 1256 B |
//| 'Pfim Tga' | .NET Core 2.1 | Tga/targa_24bit.tga | 5.645 us | 2.279 us | 0.1249 us | 0.004 | 0.0610 | - | - | 280 B |
}
}

5
tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs

@ -6,6 +6,7 @@ using System.IO;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using SixLabors.ImageSharp.Formats.Jpeg;
@ -35,8 +36,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
public ShortClr()
{
this.Add(
// Job.Clr.WithLaunchCount(1).WithWarmupCount(2).WithIterationCount(3),
Job.Core.WithLaunchCount(1).WithWarmupCount(2).WithIterationCount(3)
// Job.Default.With(ClrRuntime.Net472).WithLaunchCount(1).WithWarmupCount(2).WithIterationCount(3),
Job.Default.With(CoreRuntime.Core21).WithLaunchCount(1).WithWarmupCount(2).WithIterationCount(3)
);
}
}

3
tests/ImageSharp.Benchmarks/Codecs/MultiImageBenchmarkBase.cs

@ -17,6 +17,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using SixLabors.ImageSharp.Tests;
using CoreImage = ImageSharp.Image;
@ -36,7 +37,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
public ShortClr()
{
this.Add(
Job.Core.WithLaunchCount(1).WithWarmupCount(1).WithIterationCount(2)
Job.Default.With(CoreRuntime.Core21).WithLaunchCount(1).WithWarmupCount(1).WithIterationCount(2)
);
}
}

9
tests/ImageSharp.Benchmarks/Config.cs

@ -1,8 +1,9 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
namespace SixLabors.ImageSharp.Benchmarks
@ -19,10 +20,10 @@ namespace SixLabors.ImageSharp.Benchmarks
public ShortClr()
{
this.Add(
Job.Clr.WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3),
Job.Core.WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3)
Job.Default.With(ClrRuntime.Net472).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3),
Job.Default.With(CoreRuntime.Core21).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3)
);
}
}
}
}
}

3
tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@ -19,6 +19,7 @@
<PackageReference Include="Magick.NET-Q16-AnyCPU" />
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="Colourful" />
<PackageReference Include="Pfim" />
<PackageReference Include="SixLabors.Shapes.Text" />
<PackageReference Include="System.Drawing.Common" />
</ItemGroup>

Loading…
Cancel
Save