From c15f2328ecfac66250d3ed64ca80c3e02a72c609 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 6 Dec 2017 00:58:44 +1100 Subject: [PATCH] Minor hashing optimizations --- src/ImageSharp/Formats/Png/Zlib/Adler32.cs | 45 ++++++++----------- src/ImageSharp/Formats/Png/Zlib/Crc32.cs | 35 ++++++--------- .../ImageSharp.Benchmarks/Image/DecodePng.cs | 20 ++++++--- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/ImageSharp/Formats/Png/Zlib/Adler32.cs b/src/ImageSharp/Formats/Png/Zlib/Adler32.cs index 6841c1cb8..1cce90c0b 100644 --- a/src/ImageSharp/Formats/Png/Zlib/Adler32.cs +++ b/src/ImageSharp/Formats/Png/Zlib/Adler32.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Png.Zlib { @@ -74,9 +75,17 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib } /// - public long Value => this.checksum; + public long Value + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return this.checksum; + } + } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Reset() { this.checksum = 1; @@ -88,6 +97,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib /// /// The data value to add. The high byte of the int is ignored. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(int value) { // We could make a length 1 byte array and call update again, but I @@ -102,6 +112,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(byte[] buffer) { if (buffer == null) @@ -113,32 +124,14 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(byte[] buffer, int offset, int count) { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative"); - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative"); - } - - if (offset >= buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer"); - } - - if (offset + count > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size"); - } + DebugGuard.NotNull(buffer, nameof(buffer)); + DebugGuard.MustBeGreaterThanOrEqualTo(offset, 0, nameof(offset)); + DebugGuard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count)); + DebugGuard.MustBeLessThan(offset, buffer.Length, nameof(offset)); + DebugGuard.MustBeLessThanOrEqualTo(offset + count, buffer.Length, nameof(count)); // (By Per Bothner) uint s1 = this.checksum & 0xFFFF; @@ -169,4 +162,4 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib this.checksum = (s2 << 16) | s1; } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs b/src/ImageSharp/Formats/Png/Zlib/Crc32.cs index 14a29b7af..bd686f2b9 100644 --- a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs +++ b/src/ImageSharp/Formats/Png/Zlib/Crc32.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Png.Zlib { @@ -108,18 +109,15 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib /// public long Value { - get - { - return this.crc; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => this.crc; - set - { - this.crc = (uint)value; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => this.crc = (uint)value; } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Reset() { this.crc = 0; @@ -129,6 +127,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib /// Updates the checksum with the given value. /// /// The byte is taken as the lower 8 bits of value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(int value) { this.crc ^= CrcSeed; @@ -137,6 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(byte[] buffer) { if (buffer == null) @@ -148,22 +148,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Update(byte[] buffer, int offset, int count) { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be less than zero"); - } - - if (offset < 0 || offset + count > buffer.Length) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } + DebugGuard.NotNull(buffer, nameof(buffer)); + DebugGuard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count)); + DebugGuard.MustBeGreaterThanOrEqualTo(offset, 0, nameof(offset)); + DebugGuard.MustBeLessThanOrEqualTo(offset + count, buffer.Length, nameof(count)); this.crc ^= CrcSeed; diff --git a/tests/ImageSharp.Benchmarks/Image/DecodePng.cs b/tests/ImageSharp.Benchmarks/Image/DecodePng.cs index b9a9d5cfa..eb13cf929 100644 --- a/tests/ImageSharp.Benchmarks/Image/DecodePng.cs +++ b/tests/ImageSharp.Benchmarks/Image/DecodePng.cs @@ -10,29 +10,39 @@ namespace SixLabors.ImageSharp.Benchmarks.Image using BenchmarkDotNet.Attributes; + using SixLabors.ImageSharp.Tests; + using CoreImage = ImageSharp.Image; using CoreSize = SixLabors.Primitives.Size; + [Config(typeof(Config.ShortClr))] public class DecodePng : BenchmarkBase { private byte[] pngBytes; + private string TestImageFullPath => Path.Combine( + TestEnvironment.InputImagesDirectoryFullPath, + this.TestImage); + + [Params(TestImages.Png.Splash)] + public string TestImage { get; set; } + [GlobalSetup] public void ReadImages() { if (this.pngBytes == null) { - this.pngBytes = File.ReadAllBytes("../ImageSharp.Tests/TestImages/Formats/Png/splash.png"); + this.pngBytes = File.ReadAllBytes(this.TestImageFullPath); } } [Benchmark(Baseline = true, Description = "System.Drawing Png")] public Size PngSystemDrawing() { - using (MemoryStream memoryStream = new MemoryStream(this.pngBytes)) + using (var memoryStream = new MemoryStream(this.pngBytes)) { - using (Image image = Image.FromStream(memoryStream)) + using (var image = Image.FromStream(memoryStream)) { return image.Size; } @@ -42,9 +52,9 @@ namespace SixLabors.ImageSharp.Benchmarks.Image [Benchmark(Description = "ImageSharp Png")] public CoreSize PngCore() { - using (MemoryStream memoryStream = new MemoryStream(this.pngBytes)) + using (var memoryStream = new MemoryStream(this.pngBytes)) { - using (Image image = CoreImage.Load(memoryStream)) + using (var image = CoreImage.Load(memoryStream)) { return new CoreSize(image.Width, image.Height); }