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:
// * 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
// * 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.