diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 55940ad..8b43f53 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -59,6 +59,18 @@ jobs: - name: Test run: dotnet test --no-build --verbosity normal --configuration Release + - name: Benchmark + if: runner.os == 'Linux' + run: | + dotnet run --configuration Release --project SkiaSharpCompare.Benchmarks/SkiaSharpCompare.Benchmarks.csproj -- --artifacts ./artifacts/benchmarks + + - name: Upload benchmark artifacts + if: runner.os == 'Linux' + uses: actions/upload-artifact@v7 + with: + name: benchmark-artifacts-${{ matrix.os }} + path: ./artifacts/benchmarks + deployRelease: if: startsWith(github.ref, 'refs/heads/release') runs-on: ubuntu-latest @@ -76,7 +88,7 @@ jobs: run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - - name: Download CLI artifacts + - name: Download build artifacts uses: actions/download-artifact@v8 with: path: ./artifacts_download @@ -92,9 +104,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} if: env.GITHUB_TOKEN != '' run: | - # Attach all downloaded CLI artifacts regardless of OS - zip -r cli-artifacts.zip ./artifacts_download - gh release create ${{env.CURRENT_VERSION}} ./SkiaSharpCompare/bin/Release/*.*nupkg cli-artifacts.zip --generate-notes + # Attach downloaded build artifacts (CLI and benchmark outputs). + zip -r build-artifacts.zip ./artifacts_download + gh release create ${{env.CURRENT_VERSION}} ./SkiaSharpCompare/bin/Release/*.*nupkg build-artifacts.zip --generate-notes deployTest: if: ${{ !startsWith(github.ref, 'refs/heads/release') }} @@ -113,7 +125,7 @@ jobs: run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - - name: Download CLI artifacts + - name: Download build artifacts uses: actions/download-artifact@v8 with: path: ./artifacts_download @@ -130,5 +142,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} if: env.GITHUB_TOKEN != '' run: | - zip -r cli-artifacts.zip ./artifacts_download - gh release create ${{env.CURRENT_VERSION}} ./SkiaSharpCompare/bin/Release/*.*nupkg cli-artifacts.zip --prerelease --generate-notes + zip -r build-artifacts.zip ./artifacts_download + gh release create ${{env.CURRENT_VERSION}} ./SkiaSharpCompare/bin/Release/*.*nupkg build-artifacts.zip --prerelease --generate-notes diff --git a/SkiaSharpCompare.Benchmarks/Program.cs b/SkiaSharpCompare.Benchmarks/Program.cs new file mode 100644 index 0000000..163f15f --- /dev/null +++ b/SkiaSharpCompare.Benchmarks/Program.cs @@ -0,0 +1,47 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Running; +using Codeuctivity.SkiaSharpCompare; + +namespace SkiaSharpCompare.Benchmarks; + +public static class Program +{ + public static void Main(string[] args) + { + BenchmarkRunner.Run(); + } +} + +[MemoryDiagnoser] +public class ImagesAreEqualBenchmarks +{ + private string actualPath = string.Empty; + private string expectedPath = string.Empty; + private ImageCompare sut = null!; + + [Params(ResizeOption.Resize, ResizeOption.DontResize)] + public ResizeOption ResizeOption { get; set; } + + [Params(TransparencyOptions.CompareAlphaChannel, TransparencyOptions.IgnoreAlphaChannel)] + public TransparencyOptions TransparencyOptions { get; set; } + + [GlobalSetup] + public void Setup() + { + actualPath = Path.Combine(AppContext.BaseDirectory, "TestData", "Calc0.jpg"); + expectedPath = Path.Combine(AppContext.BaseDirectory, "TestData", "Calc0.jpg"); + + if (!File.Exists(actualPath) || !File.Exists(expectedPath)) + { + throw new FileNotFoundException($"Missing benchmark files: '{actualPath}' or '{expectedPath}'."); + } + + sut = new ImageCompare(ResizeOption, TransparencyOptions); + } + + [Benchmark] + public bool ImagesAreEqual_ByPath() + { + return sut.ImagesAreEqual(actualPath, expectedPath); + } +} diff --git a/SkiaSharpCompare.Benchmarks/SkiaSharpCompare.Benchmarks.csproj b/SkiaSharpCompare.Benchmarks/SkiaSharpCompare.Benchmarks.csproj new file mode 100644 index 0000000..0a9a137 --- /dev/null +++ b/SkiaSharpCompare.Benchmarks/SkiaSharpCompare.Benchmarks.csproj @@ -0,0 +1,25 @@ + + + + + + + + + + + + + TestData\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + + Exe + net10.0 + enable + enable + + + diff --git a/SkiaSharpCompare.sln b/SkiaSharpCompare.sln index 55a8a70..44fe809 100644 --- a/SkiaSharpCompare.sln +++ b/SkiaSharpCompare.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.0.11222.15 d18.0 +VisualStudioVersion = 18.0.11222.15 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A1B6F6C3-ECBE-471C-AE18-199DEF5982C3}" ProjectSection(SolutionItems) = preProject @@ -21,28 +21,78 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharpCompare.Cli", "Ski EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharpCompare.Cli.Tests", "SkiaSharpCompare.Cli.Tests\SkiaSharpCompare.Cli.Tests.csproj", "{059AD3EF-A494-850F-6457-E5C4D706CC94}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharpCompare.Benchmarks", "SkiaSharpCompare.Benchmarks\SkiaSharpCompare.Benchmarks.csproj", "{72AFC588-4BF8-42D4-A4E3-23F096C72823}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|x64.ActiveCfg = Debug|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|x64.Build.0 = Debug|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|x86.ActiveCfg = Debug|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Debug|x86.Build.0 = Debug|Any CPU {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|Any CPU.Build.0 = Release|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|x64.ActiveCfg = Release|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|x64.Build.0 = Release|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|x86.ActiveCfg = Release|Any CPU + {556DA894-7456-4DE2-9E02-3815FE159D7F}.Release|x86.Build.0 = Release|Any CPU {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|x64.Build.0 = Debug|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|x86.ActiveCfg = Debug|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Debug|x86.Build.0 = Debug|Any CPU {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|Any CPU.Build.0 = Release|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|x64.ActiveCfg = Release|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|x64.Build.0 = Release|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|x86.ActiveCfg = Release|Any CPU + {9CFA9A6F-92FC-40E3-BB85-4C8F95EFC8C7}.Release|x86.Build.0 = Release|Any CPU {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|x64.ActiveCfg = Debug|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|x64.Build.0 = Debug|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|x86.ActiveCfg = Debug|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Debug|x86.Build.0 = Debug|Any CPU {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|Any CPU.ActiveCfg = Release|Any CPU {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|Any CPU.Build.0 = Release|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|x64.ActiveCfg = Release|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|x64.Build.0 = Release|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|x86.ActiveCfg = Release|Any CPU + {296B4D6C-C8F6-81DE-9B65-D4CE48783B52}.Release|x86.Build.0 = Release|Any CPU {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|x64.ActiveCfg = Debug|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|x64.Build.0 = Debug|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|x86.ActiveCfg = Debug|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Debug|x86.Build.0 = Debug|Any CPU {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|Any CPU.ActiveCfg = Release|Any CPU {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|Any CPU.Build.0 = Release|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|x64.ActiveCfg = Release|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|x64.Build.0 = Release|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|x86.ActiveCfg = Release|Any CPU + {059AD3EF-A494-850F-6457-E5C4D706CC94}.Release|x86.Build.0 = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|x64.ActiveCfg = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|x64.Build.0 = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|x86.ActiveCfg = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Debug|x86.Build.0 = Debug|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|Any CPU.Build.0 = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|x64.ActiveCfg = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|x64.Build.0 = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|x86.ActiveCfg = Release|Any CPU + {72AFC588-4BF8-42D4-A4E3-23F096C72823}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE