Skip to content

Add ImageSharp benchmark - #2149

Merged
kunalspathak merged 24 commits into
dotnet:mainfrom
kunalspathak:ImageSharp
Nov 4, 2022
Merged

Add ImageSharp benchmark#2149
kunalspathak merged 24 commits into
dotnet:mainfrom
kunalspathak:ImageSharp

Conversation

@kunalspathak

Copy link
Copy Markdown
Contributor

This is a snapshot taken from SixLabors/ImageSharp@413c90c. I deleted System.Drawing* related benchmarks and most of the other 3rd party baseline benchmarks to keep things simple. I also copied few TestUtilities related code and the input images.
I ran it on Windows/x64 and Windows/arm64 and they seem to be running fine. It needs some more refining to get 100% pass rate.

Relevant discussion: SixLabors/ImageSharp#1795 (reply in thread)

FYI - @antonfirsov , @JimBobSquarePants

@JimBobSquarePants

Copy link
Copy Markdown

Will have a look ASAP. A little concerned about how to maintain this.

Ideally I would say that there would be a simple set of benchmarks that use a reference to ImageSharp via NuGet. That way anyone can PR to update the references when required.

@danmoseley

Copy link
Copy Markdown
Contributor

if you go ahead with this, there probably should be an entry in THIRD_PARTY_NOTICES.TXT

I agree with @JimBobSquarePants isn't a NuGet reference to a fixed package version sufficient? There is a lot of code here that requires building, etc.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

that use a reference to ImageSharp via NuGet

That's what I have currently. It reference to the ImageSharp version 1.0.2 via nuget. The reason there are so many files are because I copied every single benchmark file present in the original repo modulo the other baseline benchmarks. Perhaps, if there is a subset of benchmarks that you think can represent a good coverage of ImageSharp, feel free to point out and I am happy to trim it to that subset.

@antonfirsov antonfirsov left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main challenge here is that these benchmarks were developed with local execution / sandboxing in mind, many of them are garbage for dotnet/runtime performance tracking. Tried to filter those out in my review.

I'm quite sure that most of the test images are unused by the benchmarks, those are better to be deleted.

With aggressive filtering this approach (of starting with the original IS benchmark project) can work out, but there is still a lot to delete. I wonder if it would save time, if you instead tried the other way: start with an (almost) empty project (containing only the TestEnfironment infra bits), and include the benchmarks which bring value one-by-one. Less can be more here in the end of the day.

What I would include:

  • Codecs, but only individual encode/decode benchmarks, not the ones that work on multiple files
  • Individual processors, stuff like resize, rotate, blur etc.. (I couldn't find Resize, you will have to bring that here, that's our most optimized operation relying heavily on SIMD)
  • Some of the other stuff, eg. color conversion

If you manage to get rid of the noisy stuff, I can do another review.

Comment thread src/benchmarks/real-world/ImageSharp/Codecs/ImageBenchmarkTests.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg_Aggregate.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeBmpMultiple.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeGifMultiple.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeIndexedPng.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Processing/Diffuse.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Processing/Skew.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Program.cs
Comment thread src/benchmarks/real-world/ImageSharp/TestUtilities/TestImages.cs
@kunalspathak

Copy link
Copy Markdown
Contributor Author

if you go ahead with this, there probably should be an entry in THIRD_PARTY_NOTICES.TXT

Done.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

If you manage to get rid of the noisy stuff, I can do another review.

@antonfirsov - Thanks for taking time and providing feedback. I have deleted all the benchmarks that you have suggested. Do you mind doing another round of review?

@antonfirsov antonfirsov left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you pull in the new Jpeg benchmarks, add Resize benchmark, fix the memoryStream issues this should be mostly good to go.

Any insights whether the variance of execution times is within acceptable range for these benchmarks?

Comment thread src/benchmarks/real-world/ImageSharp/Codecs/DecodeFilteredPng.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeBmp.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeGif.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeGif.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeIndexedPng.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodePng.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/EncodeTga.cs Outdated
Comment thread src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs Outdated
@antonfirsov

antonfirsov commented Dec 4, 2021

Copy link
Copy Markdown

Regarding the resize benchmark:

We don't need the maxDegreeOfParallelism stuff it's outdated, resize implementation is not parallel anymore.

The subclasses exercising different scenarios are valuable, except Resize_Bicubic_Rgba32_CompareWorkBufferSizes, which can be trimmed.

@danmoseley

Copy link
Copy Markdown
Contributor

@kunalspathak are you still planning to continue with this?

@kunalspathak

Copy link
Copy Markdown
Contributor Author

@kunalspathak are you still planning to continue with this?

Yes. I have been busy with Arm64 investigation work. Will get to this soon. I don't think much work is needed here.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

Ping to myself.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

@antonfirsov , @JimBobSquarePants - I will resume working on this project now. Wondering what should be the next steps? Should I update the ImageSharp code to more latest or should we get this in as-is (after addressing the review comments) and then do another PR to update the code base to the latest?

@JimBobSquarePants

Copy link
Copy Markdown

If you are going to continue the snapshot approach I would recommend updating to the latest V2.x version before continuing. V1 numbers won't be beneficial and I can imagine you don't want to go through the PR process multiple times.

However, for ease of maintenance I would suggest that the benchmarks are performed using NuGet packages.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

If you are going to continue the snapshot approach I would recommend updating to the latest V2.x version before continuing. V1 numbers won't be beneficial and I can imagine you don't want to go through the PR process multiple times.

I agree. I will update the version in https://github.com/dotnet/performance/pull/2149/files#diff-99843982e8a5e1acef45cd069c3e3230ec1a014e7fe01aea4c05f2339b40afbc.

However, for ease of maintenance I would suggest that the benchmarks are performed using NuGet packages.

As part of this PR, ImageSharp will be consumed via nuget packages, if that's what you meant by "benchmarks are performed using NuGet packages.". My question was more around if I should take the latest benchmarks source code from ImageSharp repo or not.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

Done.

Done.

  • I would consider removing the benchmarks under the folder Color, it's an unfinished niche feature

Done.

would recommend updating to the latest V2.x version before continuing

Could you confirm the exact version that I will put in ImageSharp.Benchmarks.csproj?

@antonfirsov

Copy link
Copy Markdown

Could you confirm the exact version that I will put in ImageSharp.Benchmarks.csproj?

2.1.3

@kunalspathak

Copy link
Copy Markdown
Contributor Author

Could you confirm the exact version that I will put in ImageSharp.Benchmarks.csproj?

2.1.3

I tried that and getting these errors:

Error	NU1102	Unable to find package SixLabors.ImageSharp with version (>= 2.1.3)
  - Found 13 version(s) in dotnet-public [ Nearest version: 1.0.2 ]
  - Found 0 version(s) in benchmark-dotnet-prerelease
  - Found 0 version(s) in dotnet-eng
  - Found 0 version(s) in dotnet-tools
  - Found 0 version(s) in dotnet3.1-transport
  - Found 0 version(s) in dotnet3.1
  - Found 0 version(s) in dotnet5-transport
  - Found 0 version(s) in dotnet5
  - Found 0 version(s) in dotnet6
  - Found 0 version(s) in dotnet7	ImageSharp.Benchmarks	D:\git\performance\src\benchmarks\real-world\ImageSharp\ImageSharp.Benchmarks.csproj	1	

Also I am getting these errors for

this.Configuration.WorkingBufferSizeHintInBytes = this.WorkingBufferSizeHintInKilobytes * 1024;
Error	CS0281	Friend access was granted by 'SixLabors.ImageSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13', but the public key of the output assembly ('') does not match that specified by the InternalsVisibleTo attribute in the granting assembly.	ImageSharp.Benchmarks (net5.0)	D:\git\performance\src\benchmarks\real-world\ImageSharp\Processing\Resize.cs	79	N/A

@kunalspathak
kunalspathak marked this pull request as ready for review August 27, 2022 03:29
@kunalspathak

Copy link
Copy Markdown
Contributor Author

@antonfirsov, @JimBobSquarePants - This is ready for the review. Let me know how I can upgrade to the latest ImageSharp nuget version.

@kunalspathak

Copy link
Copy Markdown
Contributor Author

ping @antonfirsov, @JimBobSquarePants

@JimBobSquarePants

Copy link
Copy Markdown

Apologies, I’ll review over the weekend

@kunalspathak

Copy link
Copy Markdown
Contributor Author

Apologies, I’ll review over the weekend

I can understand things can be busy so just sending a friendly remainder in case it was forgotten. :)

@antonfirsov antonfirsov left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error NU1102 Unable to find package SixLabors.ImageSharp with version (>= 2.1.3)

I don't see the cause of this issue, I would have to clone the repository and try it myself to figure out. Any chance you can try to investigate? I will be on vacation the rest of the week.

/// Is it worth to set a larger working buffer limit for resize?
/// Conclusion: It doesn't really have an effect.
/// </summary>
public class Resize_Bicubic_Rgba32_CompareWorkBufferSizes : Resize_Bicubic_Rgba32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This benchmark is the cause of CS0281, it's not needed for non-regression purposes.

=> ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true);
}

public class Resize_Bicubic_Compare_Rgba32_Rgb24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, if a benchmark is about comparing A vs B, it's safe to trim it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kunalspathak this should be trimmed away,

@kunalspathak

Copy link
Copy Markdown
Contributor Author

I think I got this working with just 1 problem remaining. For some reason, I get compilation error while trying to invoke Decode() at https://github.com/kunalspathak/performance/blob/dae25ad21d40e7cc3781d45f9870a39ace45e86b/src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg.cs#L27. It resolves to ImageSharp 2.0 version code that navigates to this definition:

image

I tried clearing my nuget packages, but it doesn't help.

@antonfirsov

Copy link
Copy Markdown

The code you took is probably from the time before we changed IImageDecoder to take a CancellationToken. What if you change it like this?

- using Image img = this.decoder.Decode(Configuration.Default, this.preloadedImageStream);
+ using Image img = this.decoder.Decode(Configuration.Default, this.preloadedImageStream, default);

@kunalspathak

Copy link
Copy Markdown
Contributor Author

What if you change it like this?

that works. Wanted to make sure if default is fine with benchmark code. Any other comments or should it be good to go?

@kunalspathak

Copy link
Copy Markdown
Contributor Author

Ping @antonfirsov and @JimBobSquarePants

@JimBobSquarePants

Copy link
Copy Markdown

I cannot see anything out of the ordinary 👍

@kunalspathak

Copy link
Copy Markdown
Contributor Author

I cannot see anything out of the ordinary 👍

Thanks for confirming @JimBobSquarePants and thank you for the valuable feedback. @sblom - This one is another "real-world" benchmark we would like to merge.

@antonfirsov antonfirsov left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good in general, but noticed one point from previous review that was not addressed. Might worth a final self-review if there's anything left that can be trimmed away.

=> ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true);
}

public class Resize_Bicubic_Compare_Rgba32_Rgb24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kunalspathak this should be trimmed away,

@kunalspathak

Copy link
Copy Markdown
Contributor Author

one point from previous review that was not addressed.
Fixed.

Might worth a final self-review if there's anything left that can be trimmed away.

We are now with following benchmarks:

SixLabors
 └─ImageSharp
    └─Benchmarks
       ├─DetectEdges
       │  └─ImageProcessorCoreDetectEdges
       ├─Resize_Bicubic_Rgb24
       │  └─ImageSharp_P1
       ├─Resize_Bicubic_Rgba32
       │  └─ImageSharp_P1
       ├─Codecs
       │  ├─DecodeBmp
       │  │  └─BmpImageSharp
       │  ├─DecodeFilteredPng
       │  │  ├─PngFilter0
       │  │  ├─PngFilter1
       │  │  ├─PngFilter2
       │  │  ├─PngFilter3
       │  │  └─PngFilter4
       │  ├─DecodeGif
       │  │  └─GifImageSharp
       │  ├─DecodePng
       │  │  └─PngImageSharp
       │  ├─DecodeTga
       │  │  └─TgaImageSharp
       │  ├─EncodeBmp
       │  │  └─BmpImageSharp
       │  ├─EncodeGif
       │  │  └─GifImageSharp
       │  ├─EncodeIndexedPng
       │  │  ├─PngCoreOctree
       │  │  ├─PngCoreOctreeNoDither
       │  │  ├─PngCorePalette
       │  │  ├─PngCorePaletteNoDither
       │  │  ├─PngCoreWu
       │  │  └─PngCoreWuNoDither
       │  ├─EncodePng
       │  │  └─PngCore
       │  ├─EncodeTga
       │  │  └─ImageSharpTga
       │  └─Jpeg
       │     └─DecodeJpeg
       │        ├─JpegBaselineInterleaved444
       │        ├─JpegBaselineInterleaved420
       │        ├─JpegBaseline400
       │        └─JpegProgressiveNonInterleaved420
       ├─Processing
       │  ├─BokehBlur
       │  │  └─Blur
       │  ├─Crop
       │  │  └─CropImageSharp
       │  ├─Diffuse
       │  │  ├─DoDiffuse
       │  │  └─DoDither
       │  ├─HistogramEqualization
       │  │  ├─GlobalHistogramEqualization
       │  │  └─AdaptiveHistogramEqualization
       │  └─Rotate
       │     └─DoRotate
       └─Samplers
          └─GaussianBlur
             └─Blur

@kunalspathak
kunalspathak merged commit 7a7ac6f into dotnet:main Nov 4, 2022
@kunalspathak
kunalspathak deleted the ImageSharp branch November 4, 2022 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants