From 221e29be314850819dfcf6c6116baf96076401c9 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 24 Aug 2016 13:05:16 +1000 Subject: [PATCH] Benchmark CopyRow touch #457 [skip ci] Former-commit-id: 3ebb26faca837aeac974a67da676be409d902ae7 Former-commit-id: d7a8a733fabfb6621f8f3a04c56b9f2aa6913392 Former-commit-id: ec769799df83b3f7b1d4934aead8e6ae1e280736 --- src/ImageProcessorCore/Image/PixelAccessor.cs | 19 +++++++ .../General/{Copy.cs => ArrayCopy.cs} | 2 +- .../Image/CopyPixels.cs | 57 +++++++++++++++++++ .../Samplers/Crop.cs | 4 +- 4 files changed, 79 insertions(+), 3 deletions(-) rename tests/ImageProcessorCore.Benchmarks/General/{Copy.cs => ArrayCopy.cs} (96%) create mode 100644 tests/ImageProcessorCore.Benchmarks/Image/CopyPixels.cs diff --git a/src/ImageProcessorCore/Image/PixelAccessor.cs b/src/ImageProcessorCore/Image/PixelAccessor.cs index 1c5227055..d7146e4aa 100644 --- a/src/ImageProcessorCore/Image/PixelAccessor.cs +++ b/src/ImageProcessorCore/Image/PixelAccessor.cs @@ -108,6 +108,25 @@ namespace ImageProcessorCore set { Unsafe.Write(this.pixelsBase + (y * this.Width + x) * Unsafe.SizeOf(), value); } } + /// + /// Copies an entire row of pixels. + /// + /// The x-coordinate of the source row. + /// The y-coordinate of the source row. + /// The target pixel buffer accessor. + /// The x-coordinate of the target row. + /// The y-coordinate of the target row. + /// The number of pixels to copy + public void CopyRow(int sourceX, int sourceY, PixelAccessor target, int targetX, int targetY, int pixelCount) + { + int size = Unsafe.SizeOf(); + byte* sourcePtr = this.pixelsBase + (sourceY * this.Width + sourceX) * size; + byte* targetPtr = target.pixelsBase + (targetY * target.Width + targetX) * size; + uint byteCount = (uint)(pixelCount * size); + + Unsafe.CopyBlock(targetPtr, sourcePtr, byteCount); + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// diff --git a/tests/ImageProcessorCore.Benchmarks/General/Copy.cs b/tests/ImageProcessorCore.Benchmarks/General/ArrayCopy.cs similarity index 96% rename from tests/ImageProcessorCore.Benchmarks/General/Copy.cs rename to tests/ImageProcessorCore.Benchmarks/General/ArrayCopy.cs index de4dadffb..349c94fa3 100644 --- a/tests/ImageProcessorCore.Benchmarks/General/Copy.cs +++ b/tests/ImageProcessorCore.Benchmarks/General/ArrayCopy.cs @@ -5,7 +5,7 @@ namespace ImageProcessorCore.Benchmarks.General { using BenchmarkDotNet.Attributes; - public class Copy + public class ArrayCopy { private double[] source = new double[10000]; diff --git a/tests/ImageProcessorCore.Benchmarks/Image/CopyPixels.cs b/tests/ImageProcessorCore.Benchmarks/Image/CopyPixels.cs new file mode 100644 index 000000000..df0706bc6 --- /dev/null +++ b/tests/ImageProcessorCore.Benchmarks/Image/CopyPixels.cs @@ -0,0 +1,57 @@ +namespace ImageProcessorCore.Benchmarks.Image +{ + using System.Threading.Tasks; + + using BenchmarkDotNet.Attributes; + + using CoreColor = ImageProcessorCore.Color; + using CoreImage = ImageProcessorCore.Image; + + public class CopyPixels + { + [Benchmark(Description = "Copy by Pixel")] + public CoreColor CopyByPixel() + { + CoreImage source = new CoreImage(1024, 768); + CoreImage target = new CoreImage(1024, 768); + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + 0, + source.Height, + Bootstrapper.Instance.ParallelOptions, + y => + { + for (int x = 0; x < source.Width; x++) + { + targetPixels[x, y] = sourcePixels[x, y]; + } + }); + + return targetPixels[0, 0]; + } + } + + [Benchmark(Description = "Copy by Row")] + public CoreColor CopyByRow() + { + CoreImage source = new CoreImage(1024, 768); + CoreImage target = new CoreImage(1024, 768); + using (PixelAccessor sourcePixels = source.Lock()) + using (PixelAccessor targetPixels = target.Lock()) + { + Parallel.For( + 0, + source.Height, + Bootstrapper.Instance.ParallelOptions, + y => + { + sourcePixels.CopyRow(0, y, targetPixels, 0, y, source.Width); + }); + + return targetPixels[0, 0]; + } + } + } +} diff --git a/tests/ImageProcessorCore.Benchmarks/Samplers/Crop.cs b/tests/ImageProcessorCore.Benchmarks/Samplers/Crop.cs index 4eaeea6ec..ef7cb9722 100644 --- a/tests/ImageProcessorCore.Benchmarks/Samplers/Crop.cs +++ b/tests/ImageProcessorCore.Benchmarks/Samplers/Crop.cs @@ -12,7 +12,7 @@ [Benchmark(Baseline = true, Description = "System.Drawing Crop")] public Size CropSystemDrawing() { - using (Bitmap source = new Bitmap(400, 400)) + using (Bitmap source = new Bitmap(800, 800)) { using (Bitmap destination = new Bitmap(100, 100)) { @@ -32,7 +32,7 @@ [Benchmark(Description = "ImageProcessorCore Crop")] public CoreSize CropResizeCore() { - CoreImage image = new CoreImage(400, 400); + CoreImage image = new CoreImage(800, 800); image.Crop(100, 100); return new CoreSize(image.Width, image.Height); }