This is a ridiculously short post for .NET devs looking to compare System.Drawing
with SkiaSharp
(the fastest open-source alternative).
I'm currently building a new pet project - a free tool, that will allow bloggers and webmasters generate open-graph "cover images" via sending GET requests to a simple API and then hot-linking images right into their pages. That is why I was in need of a fast, simple and scalable image processing library for .NET:
For those unaware, System.Drawing
is an image manipulation and generation tool that is part of .NET Framework. But since it depends on Windows so much - it was not included in .NET Core. That is why developers mostly use ImageSharp
and SkiaSharp
(SkiaSharp is faster but comes with a C++ library, ImageSharp is slower, but it's 100% managed code).
Now that System.Drawing.Common is finally available for .NET Core and is even cross-platform, it's time to give it a try.
System.Drawing
gets a lot of hate. There are dozens of posts why you shouldn't be using it: high CPU load, concurrency issues, slow performance etc. I decided to test that last one and benchmark it against the fastest alternative - SkiaSharp. It is based on Google Skia, a portable image manipulation API from the big G. The code generates a 120x80 thumbnail from a 500kb picture. Here are the results:
.NET Framework
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
[Host] : .NET Framework 4.8 (4.8.4341.0), X86 LegacyJIT
Job-YOWEFT : .NET Framework 4.8 (4.8.4341.0), X86 LegacyJIT
IterationCount=10 LaunchCount=1 WarmupCount=1
| Method | Mean | Error | StdDev |
|----------------------------- |---------:|----------:|----------:|
| CreateThumbnailSystemDrawing | 6.733 ms | 0.3119 ms | 0.1856 ms |
| CreateThumbnailSkiaSharp | 7.421 ms | 0.1057 ms | 0.0629 ms |
As you can see System.Drawing is faster, at least on Windows. I tried it with different images, played around with different settings to make SkiaSharp faster (with or without anti-aliasing, different interpolation techniques etc.) and the results were consistent: System.Drawing was always better.
But may be it's just .NET Framework using some unfair tricks? Let's test on .NET Core
.NET Core 5.0
// * Summary *
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.201
[Host] : .NET Core 5.0.4 (CoreCLR 5.0.421.11614, CoreFX 5.0.421.11614), X64 RyuJIT
Job-IFFNJZ : .NET Core 5.0.4 (CoreCLR 5.0.421.11614, CoreFX 5.0.421.11614), X64 RyuJIT
IterationCount=10 LaunchCount=1 WarmupCount=1
| Method | Mean | Error | StdDev |
|----------------------------- |---------:|----------:|----------:|
| CreateThumbnailSystemDrawing | 5.458 ms | 0.2266 ms | 0.1499 ms |
| CreateThumbnailSkiaSharp | 7.325 ms | 0.9527 ms | 0.6302 ms |
Wow, that's even a bigger difference. Almost 1.5x faster than SkiaSharp. The old dog is still kicking.
Originally published here
Top comments (6)
Do you have the source code for the benchmark available? I'd like to see how the latest ImageSharp builds compare in your scenario. We're able to beat both now in this benchmark.
github.com/bleroy/core-imaging-pla...
Sure. I'm a little embarrassed by it, but sure :) Where do you want me to put it? Gist?
Yeah that would be great, thanks! (Nothing to be embarrassed about, it's all super useful to me!)
If you could upload a relevant test image also that'd be awesome!
there you go gist.github.com/alex-jitbit/4fb52e...
Hey there! Nice post, but I am just wondering why you have a resize for the bitmap in the SkiaSharp benchmark? This adds an extra copy to the process.
Because resizing is what I’m benchmarking.