Skip to content

qmfrederik/libpng-sharp

Repository files navigation

libpng-sharp

Build status Build Status

This repository contains some sample code on how you can call libpng from C#.

The code was written to test whether calling libpng natively could be an alternative, performance-wise, for System.Drawing to decode PNG images.

What I found out was:

  • Decoding PNG images very slow compared to other formats (for example, jpeg using libjpeg-turbo)
  • GDI+ seemed to be at least as performant as libpng on Windows, but libpng is a winner on Linux and macOS
  • On Mono, System.Drawing uses libgdiplus which uses libpng under the hood.

Conclusion:

  • On Windows, you may want to keep using System.Drawing
  • On Linux and macOS, libpng is a better option, performance-wise

libpng uses zlib, of which various forks exist which contain additional performance improvements. These forks have not been tested.

Benchmark Results - decoding to library-native format

There are Travis and AppVeyor builds which run benchmarks. The list below gives a snapshot of the results:

Windows

// * Summary *

BenchmarkDotNet=v0.10.14, OS=Windows 8.1 (6.3.9600.0)
Intel Xeon CPU E5-2697 v3 2.60GHz, 1 CPU, 2 logical and 2 physical cores
.NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core

               Method |       Mean |     Error |    StdDev |
--------------------- |-----------:|----------:|----------:|
 ImageSharpDecompress | 1,132.6 ms | 13.356 ms | 12.493 ms |
     LibPngDecompress |   932.8 ms |  4.741 ms |  4.435 ms |
    DrawingDecompress |   783.0 ms |  5.968 ms |  5.290 ms |

Linux

// * Summary *

BenchmarkDotNet=v0.10.14, OS=ubuntu 16.04
Intel Xeon CPU 2.50GHz, 1 CPU, 2 logical cores and 1 physical core
.NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core  

               Method |    Mean |    Error |   StdDev |
--------------------- |--------:|---------:|---------:|
 ImageSharpDecompress | 1.408 s | 0.0273 s | 0.0335 s |
     LibPngDecompress | 1.227 s | 0.0208 s | 0.0195 s |
    DrawingDecompress |      NA |       NA |       NA |

macOS

// * Summary *

BenchmarkDotNet=v0.10.14, OS=macOS Sierra 10.12.6 (16G29) [Darwin 16.7.0]
Intel Xeon CPU E5-2697 v2 2.70GHz, 2 CPU, 2 logical and 2 physical cores
.NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core

               Method |    Mean |    Error |   StdDev |
--------------------- |--------:|---------:|---------:|
 ImageSharpDecompress | 1.266 s | 0.0245 s | 0.0229 s |
     LibPngDecompress | 1.027 s | 0.0156 s | 0.0146 s |
    DrawingDecompress | 1.481 s | 0.0042 s | 0.0033 s |

Benchmark Results - Decoding to BGR24

Windows

// * Summary *

NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core

               Method |       Mean |     Error |    StdDev |
--------------------- |-----------:|----------:|----------:|
 ImageSharpDecompress | 1,607.5 ms |  4.248 ms |  3.973 ms |
     LibPngDecompress | 1,153.8 ms | 10.889 ms | 10.186 ms |
    DrawingDecompress |   948.6 ms | 18.685 ms | 19.992 ms |

Linux

// * Summary *

BenchmarkDotNet=v0.10.14, OS=ubuntu 16.04
Intel Xeon CPU 2.50GHz, 1 CPU, 2 logical cores and 1 physical core
.NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core  9m

               Method |    Mean |    Error |   StdDev |
--------------------- |--------:|---------:|---------:|
 ImageSharpDecompress | 1.672 s | 0.0334 s | 0.0397 s |
     LibPngDecompress | 1.226 s | 0.0209 s | 0.0195 s |
    DrawingDecompress | 1.896 s | 0.0250 s | 0.0234 s |

macOS

// * Summary *
BenchmarkDotNet=v0.10.14, OS=macOS Sierra 10.12.6 (16G29) [Darwin 16.7.0]
Intel Xeon CPU E5-2697 v2 2.70GHz, 2 CPU, 2 logical and 2 physical cores
.NET Core SDK=2.1.300
  [Host] : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT
  Core   : .NET Core 2.1.0 (CoreCLR 4.6.26515.07, CoreFX 4.6.26515.06), 64bit RyuJIT

Job=Core  Runtime=Core

               Method |    Mean |    Error |   StdDev |9m
--------------------- |--------:|---------:|---------:|
 ImageSharpDecompress | 1.537 s | 0.0300 s | 0.0281 s |
     LibPngDecompress | 1.073 s | 0.0145 s | 0.0135 s |
    DrawingDecompress | 1.497 s | 0.0116 s | 0.0108 s |

Releases

No releases published

Packages

No packages published

Languages