Skip to content

WebP - Improve performance  #1786

Closed
Closed

Description

@JimBobSquarePants

TomCruiseNeedForSpeedGIF

Now that WebP has been merged #1552 into master we need to polish the performance to bring it up to speed for the release of V2.

We're looking for community contribution here while we focus on bring the Drawing/Fonts libraries up to RC status and also work on the new Unamanaged Memory allocator #1730 so anyone who like to make things go fast please have a crack.

Benchmarks

The last benchmarks (June 2021) indicate that we're a good bit slower than the Magick.NET implementation. (There's a positive here, potentially lots of low hanging fruit)

Decode

Big improvements in .NET Core with some SIMD which is positive. Definitely some allocations to deal with but will require profiling to determine if something else is in play.

Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.202
    [Host]     : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
    Job-AQFZAV : .NET Framework 4.8 (4.8.4180.0), X64 RyuJIT
    Job-YCDAPQ : .NET Core 2.1.18 (CoreCLR 4.6.28801.04, CoreFX 4.6.28802.05), X64 RyuJIT
    Job-WMTYOZ : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT

IterationCount=3  LaunchCount=1  WarmupCount=3
|                     Method |        Job |       Runtime |        TestImageLossy |        TestImageLossless |       Mean |     Error |   StdDev |     Gen 0 |     Gen 1 | Gen 2 |   Allocated |
|--------------------------- |----------- |-------------- |---------------------- |------------------------- |-----------:|----------:|---------:|----------:|----------:|------:|------------:|
|        'Magick Lossy Webp' | Job-IERNAB |    .NET 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   105.8 ms |   6.28 ms |  0.34 ms |         - |         - |     - |    17.65 KB |
|    'ImageSharp Lossy Webp' | Job-IERNAB |    .NET 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,145.0 ms | 110.82 ms |  6.07 ms |         - |         - |     - |  2779.53 KB |
|     'Magick Lossless Webp' | Job-IERNAB |    .NET 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   145.9 ms |   8.55 ms |  0.47 ms |         - |         - |     - |    18.05 KB |
| 'ImageSharp Lossless Webp' | Job-IERNAB |    .NET 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,694.1 ms |  55.09 ms |  3.02 ms | 4000.0000 | 1000.0000 |     - | 30556.87 KB |
|        'Magick Lossy Webp' | Job-IMRAGJ | .NET Core 2.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   105.7 ms |   1.89 ms |  0.10 ms |         - |         - |     - |    15.75 KB |
|    'ImageSharp Lossy Webp' | Job-IMRAGJ | .NET Core 2.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   741.6 ms |  21.45 ms |  1.18 ms |         - |         - |     - |  2767.85 KB |
|     'Magick Lossless Webp' | Job-IMRAGJ | .NET Core 2.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   146.1 ms |   9.52 ms |  0.52 ms |         - |         - |     - |    16.54 KB |
| 'ImageSharp Lossless Webp' | Job-IMRAGJ | .NET Core 2.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   522.5 ms |  21.15 ms |  1.16 ms | 4000.0000 | 1000.0000 |     - | 22860.02 KB |
|        'Magick Lossy Webp' | Job-NAASQX | .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   105.9 ms |   5.34 ms |  0.29 ms |         - |         - |     - |    15.45 KB |
|    'ImageSharp Lossy Webp' | Job-NAASQX | .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   748.8 ms | 290.47 ms | 15.92 ms |         - |         - |     - |  2767.84 KB |
|     'Magick Lossless Webp' | Job-NAASQX | .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   146.1 ms |   1.14 ms |  0.06 ms |         - |         - |     - |     15.9 KB |
| 'ImageSharp Lossless Webp' | Job-NAASQX | .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   480.7 ms |  25.25 ms |  1.38 ms | 4000.0000 | 1000.0000 |     - |  22859.7 KB |
|        'Magick Lossy Webp' | Job-GLNACU | .NET Core 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   105.7 ms |   4.71 ms |  0.26 ms |         - |         - |     - |    15.48 KB |
|    'ImageSharp Lossy Webp' | Job-GLNACU | .NET Core 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   645.7 ms |  61.00 ms |  3.34 ms |         - |         - |     - |  2768.13 KB |
|     'Magick Lossless Webp' | Job-GLNACU | .NET Core 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   146.5 ms |  18.63 ms |  1.02 ms |         - |         - |     - |     15.8 KB |
| 'ImageSharp Lossless Webp' | Job-GLNACU | .NET Core 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   306.7 ms |  32.31 ms |  1.77 ms | 4000.0000 | 1000.0000 |     - | 22860.02 KB |

Encode

The current implementation suffers from heavy allocations but I suspect a lot of that is low hanging fruit which we can refactor to use our MemoryAllocator types. The lack of difference between NET 472 and NET 5 suggests we have some SIMD opportunities also.

BenchmarkDotNet = v0.12.1, OS = Windows 10.0.19041.630 (2004/?/20H1)
Intel Core i7-6700K CPU 4.00GHz(Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK = 5.0.100

    [Host]     : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
    Job-OUUGWL : .NET Framework 4.8 (4.8.4250.0), X64 RyuJIT
    Job-GAIITM : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
    Job-HWOBSO : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT

|                     Method |        Job |       Runtime |    TestImage |      Mean |      Error |    StdDev | Ratio | RatioSD |      Gen 0 |     Gen 1 |     Gen 2 |    Allocated |
|--------------------------- |----------- |-------------- |------------- |----------:|-----------:|----------:|------:|--------:|-----------:|----------:|----------:|-------------:|
|        'Magick Webp Lossy' | Job-RYVNHD |    .NET 4.7.2 | Png/Bike.png |  23.30 ms |   0.869 ms |  0.048 ms |  0.14 |    0.00 |          - |         - |         - |     68.19 KB |
|    'ImageSharp Webp Lossy' | Job-RYVNHD |    .NET 4.7.2 | Png/Bike.png |  68.22 ms |  16.454 ms |  0.902 ms |  0.42 |    0.01 |  6125.0000 |  125.0000 |         - |  26359.49 KB |
|     'Magick Webp Lossless' | Job-RYVNHD |    .NET 4.7.2 | Png/Bike.png | 161.96 ms |   9.879 ms |  0.541 ms |  1.00 |    0.00 |          - |         - |         - |    520.28 KB |
| 'ImageSharp Webp Lossless' | Job-RYVNHD |    .NET 4.7.2 | Png/Bike.png | 370.88 ms |  58.875 ms |  3.227 ms |  2.29 |    0.02 | 34000.0000 | 5000.0000 | 2000.0000 | 163177.15 KB |
|                            |            |               |              |           |            |           |       |         |            |           |           |              |
|        'Magick Webp Lossy' | Job-GOZXWU | .NET Core 2.1 | Png/Bike.png |  23.35 ms |   0.428 ms |  0.023 ms |  0.14 |    0.00 |          - |         - |         - |     67.76 KB |
|    'ImageSharp Webp Lossy' | Job-GOZXWU | .NET Core 2.1 | Png/Bike.png |  43.95 ms |   2.850 ms |  0.156 ms |  0.27 |    0.00 |  6250.0000 |  250.0000 |   83.3333 |  26284.72 KB |
|     'Magick Webp Lossless' | Job-GOZXWU | .NET Core 2.1 | Png/Bike.png | 161.44 ms |   3.749 ms |  0.206 ms |  1.00 |    0.00 |          - |         - |         - |    519.26 KB |
| 'ImageSharp Webp Lossless' | Job-GOZXWU | .NET Core 2.1 | Png/Bike.png | 335.78 ms |  78.666 ms |  4.312 ms |  2.08 |    0.03 | 34000.0000 | 5000.0000 | 2000.0000 | 162727.56 KB |
|                            |            |               |              |           |            |           |       |         |            |           |           |              |
|        'Magick Webp Lossy' | Job-VRDVKW | .NET Core 3.1 | Png/Bike.png |  23.48 ms |   4.325 ms |  0.237 ms |  0.15 |    0.00 |          - |         - |         - |     67.66 KB |
|    'ImageSharp Webp Lossy' | Job-VRDVKW | .NET Core 3.1 | Png/Bike.png |  43.29 ms |  16.503 ms |  0.905 ms |  0.27 |    0.01 |  6272.7273 |  272.7273 |   90.9091 |  26284.86 KB |
|     'Magick Webp Lossless' | Job-VRDVKW | .NET Core 3.1 | Png/Bike.png | 161.81 ms |  10.693 ms |  0.586 ms |  1.00 |    0.00 |          - |         - |         - |    523.25 KB |
| 'ImageSharp Webp Lossless' | Job-VRDVKW | .NET Core 3.1 | Png/Bike.png | 323.97 ms | 235.468 ms | 12.907 ms |  2.00 |    0.08 | 34000.0000 | 5000.0000 | 2000.0000 | 162724.84 KB |
|                            |            |               |              |           |            |           |       |         |            |           |           |              |
|        'Magick Webp Lossy' | Job-ZJRLRB | .NET Core 5.0 | Png/Bike.png |  23.36 ms |   0.448 ms |  0.025 ms |  0.14 |    0.00 |          - |         - |         - |     67.66 KB |
|    'ImageSharp Webp Lossy' | Job-ZJRLRB | .NET Core 5.0 | Png/Bike.png |  40.11 ms |   2.465 ms |  0.135 ms |  0.25 |    0.00 |  6307.6923 |  230.7692 |   76.9231 |  26284.71 KB |
|     'Magick Webp Lossless' | Job-ZJRLRB | .NET Core 5.0 | Png/Bike.png | 161.55 ms |   6.662 ms |  0.365 ms |  1.00 |    0.00 |          - |         - |         - |    518.84 KB |
| 'ImageSharp Webp Lossless' | Job-ZJRLRB | .NET Core 5.0 | Png/Bike.png | 298.73 ms |  17.953 ms |  0.984 ms |  1.85 |    0.01 | 34000.0000 | 5000.0000 | 2000.0000 | 162725.13 KB |

Activity

  1. added this to the milestone on Oct 23, 2021
  2. SebastianStehle commented on Oct 26, 2021

    @SebastianStehle

    Would some sponsoring help for this task? I would really like to see webp support.

  3. JimBobSquarePants commented on Oct 26, 2021

    @JimBobSquarePants
    MemberAuthor

    Sponsorship is always welcome but it’s really a matter of resources which can be provided by the community if willing. In the interim you can download preview builds from our MyGet feed.

  4. SebastianStehle commented on Oct 26, 2021

    @SebastianStehle

    I am using imagesharp in a server environment. I am afraid to use it in production currently as it has the potential to bring the CPU down.

    I will see if I find the time (and knowledge) to help, but I guess you are much more familiar with this low level code than must other developers. I don't know whether you work as a freelancer or employee but I guess if you would have the chance to work on this for 1-2 weeks the results would be amazing.

  5. JimBobSquarePants commented on Oct 26, 2021

    @JimBobSquarePants
    MemberAuthor

    I am using imagesharp in a server environment. I am afraid to use it in production currently as it has the potential to bring the CPU down.

    Our MyGet build is exactly the same as our NuGet ones we just don't tag them. Things are subject to change but do go through 30,000+ unit tests. We've still got #1730 to complete before we can consider shipping V2 I'm afraid so we cannot ship a stable build until then.

    I don't know whether you work as a freelancer or employee but I guess if you would have the chance to work on this for 1-2 weeks the results would be amazing.

    Everyone contributing to Six Labors is doing so in their spare time - There's not been enough financial support from the software industry for me to be able to work full time on the projects (hopefully one day). I personally attempt to get some work done most nights between 11pm and 2am.

  6. SebastianStehle commented on Oct 26, 2021

    @SebastianStehle

    Everyone contributing to Six Labors is doing so in their spare time - There's not been enough financial support from the software industry for me to be able to work full time on the projects (hopefully one day). I personally attempt to get some work done most nights between 11pm and 2am.

    Yes, I assumed that it works like this, therefore I asked if I can support the team financially by sponsoring this task, at least partially.

  7. brianpopow commented on Oct 30, 2021

    @brianpopow
    Collaborator

    @SebastianStehle:

    Would some sponsoring help for this task? I would really like to see webp support.

    Getting some donation for doing the work here would be very welcome. I think most people really underestimate how much work it really is.
    It took me almost 2 years to get webp done. Of course this was most of the time in the same mode as James mentioned: nights and weekends.

    I guess if you would have the chance to work on this for 1-2 weeks the results would be amazing.

    I am not sure that we can achieve that much in that short time period to be honest.
    Also keep in mind that encoding webp is a CPU intense task, no matter how much optimization we do (i assume that's your usecase).

    I am currently working on reducing the allocations. I have an experimental branch,
    which uses 1/20 of the allocations for lossy encoding and 1/2 for lossless.

    I think the first step for improving the performance should be, that someone does
    extensive profiling and spots places which would benefit the most from optimization.
    That would already be pretty helpful.

    As James mentioned, hardware intrinsics are the way to go for performance gains.
    The original libwebp source contains a lot of hardware intrinsics usages.
    They can be easily spotted, because the files have the suffix sse2 or sse41.
    I tried to keep the original function names as they are in the libwebp source.
    I have ported already some of them, but there are plenty left.

  8. linked a pull request that will close this issueWebp encoding: Reduce allocations. #1799on Oct 31, 2021
  9. 8 remaining items

  10. brianpopow commented on Nov 2, 2021

    @brianpopow
    Collaborator

    Sorry for that closing and reopening again, same issue as before: just wanted to link an PR to this issue.

  11. JimBobSquarePants commented on Nov 2, 2021

    @JimBobSquarePants
    MemberAuthor

    @brianpopow Rather than manually linking (which always closes when PRs are merged into the default branch) you can just use the hash syntax without closing keywords.

  12. brianpopow commented on Nov 4, 2021

    @brianpopow
    Collaborator

    Unfortunately i noticed a big difference between the lossy encoding benchmarks posted here initially
    and the current ones. The current ones look much worse, but after digging deeper into it,
    it seems the original benchmarks from June 2021 were made without all features implemented.

    The commit which introduced this is a368f41. I will recreate new benchmarks from the point
    when we merged it into master, so we have a better baseline.
    We also need to double check, if the reference decoder/encoder uses the same parameters as we are.
    The results can differ very largely with different parameters, especially when encoding.

  13. brianpopow commented on Nov 8, 2021

    @brianpopow
    Collaborator

    I have re-run the benchmarks again for the commit: 853c40c from 23. October, which was the commit merging webp into master.
    I assume we stay with the same settings proposed in #1808.

    Encode:

    BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1320 (21H1/May2021Update)
    Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
    .NET SDK=6.0.100-rc.2.21505.57
      [Host]     : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT
      Job-MCQRNW : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT
      Job-MKUBKO : .NET Core 3.1.20 (CoreCLR 4.700.21.47003, CoreFX 4.700.21.47101), X64 RyuJIT
      Job-DQBIQV : .NET Framework 4.8 (4.8.4420.0), X64 RyuJIT
    
    IterationCount=3  LaunchCount=1  WarmupCount=3
    
    |                     Method |        Job |              Runtime |    TestImage |      Mean |      Error |    StdDev | Ratio | RatioSD |       Gen 0 |     Gen 1 |     Gen 2 |  Allocated |
    |--------------------------- |----------- |--------------------- |------------- |----------:|-----------:|----------:|------:|--------:|------------:|----------:|----------:|-----------:|
    |        'Magick Webp Lossy' | Job-BGVUUM |             .NET 5.0 | Png/Bike.png |  24.94 ms |  14.459 ms |  0.793 ms |  0.15 |    0.00 |           - |         - |         - |      67 KB |
    |    'ImageSharp Webp Lossy' | Job-BGVUUM |             .NET 5.0 | Png/Bike.png | 258.31 ms | 115.015 ms |  6.304 ms |  1.56 |    0.04 | 135000.0000 |         - |         - | 552,714 KB |
    |     'Magick Webp Lossless' | Job-BGVUUM |             .NET 5.0 | Png/Bike.png | 165.43 ms |   6.883 ms |  0.377 ms |  1.00 |    0.00 |           - |         - |         - |     518 KB |
    | 'ImageSharp Webp Lossless' | Job-BGVUUM |             .NET 5.0 | Png/Bike.png | 342.17 ms | 304.705 ms | 16.702 ms |  2.07 |    0.11 |  34000.0000 | 5000.0000 | 2000.0000 | 161,672 KB |
    |                            |            |                      |              |           |            |           |       |         |             |           |           |            |
    |        'Magick Webp Lossy' | Job-HPMKSN |        .NET Core 3.1 | Png/Bike.png |  23.80 ms |   0.471 ms |  0.026 ms |  0.14 |    0.00 |           - |         - |         - |      67 KB |
    |    'ImageSharp Webp Lossy' | Job-HPMKSN |        .NET Core 3.1 | Png/Bike.png | 264.16 ms |  46.068 ms |  2.525 ms |  1.60 |    0.05 | 135000.0000 |         - |         - | 552,713 KB |
    |     'Magick Webp Lossless' | Job-HPMKSN |        .NET Core 3.1 | Png/Bike.png | 165.15 ms |  64.844 ms |  3.554 ms |  1.00 |    0.00 |           - |         - |         - |     520 KB |
    | 'ImageSharp Webp Lossless' | Job-HPMKSN |        .NET Core 3.1 | Png/Bike.png | 321.60 ms |  26.428 ms |  1.449 ms |  1.95 |    0.04 |  34000.0000 | 5000.0000 | 2000.0000 | 161,668 KB |
    |                            |            |                      |              |           |            |           |       |         |             |           |           |            |
    |        'Magick Webp Lossy' | Job-BOAJTS | .NET Framework 4.7.2 | Png/Bike.png |  23.68 ms |   3.686 ms |  0.202 ms |  0.14 |    0.00 |           - |         - |         - |      68 KB |
    |    'ImageSharp Webp Lossy' | Job-BOAJTS | .NET Framework 4.7.2 | Png/Bike.png | 385.60 ms |  48.371 ms |  2.651 ms |  2.35 |    0.02 | 135000.0000 |         - |         - | 554,351 KB |
    |     'Magick Webp Lossless' | Job-BOAJTS | .NET Framework 4.7.2 | Png/Bike.png | 164.32 ms |   8.850 ms |  0.485 ms |  1.00 |    0.00 |           - |         - |         - |     518 KB |
    | 'ImageSharp Webp Lossless' | Job-BOAJTS | .NET Framework 4.7.2 | Png/Bike.png | 390.85 ms |  30.365 ms |  1.664 ms |  2.38 |    0.00 |  34000.0000 | 5000.0000 | 2000.0000 | 162,117 KB |
    

    Decode:

    |                     Method |        Job |              Runtime |        TestImageLossy |        TestImageLossless |       Mean |     Error |   StdDev |     Gen 0 |     Gen 1 |    Gen 2 | Allocated |
    |--------------------------- |----------- |--------------------- |---------------------- |------------------------- |-----------:|----------:|---------:|----------:|----------:|---------:|----------:|
    |        'Magick Lossy Webp' | Job-EJYKMG |             .NET 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   105.6 ms |   0.98 ms |  0.05 ms |         - |         - |        - |     25 KB |
    |    'ImageSharp Lossy Webp' | Job-EJYKMG |             .NET 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   669.9 ms | 280.92 ms | 15.40 ms |         - |         - |        - |  2,770 KB |
    |     'Magick Lossless Webp' | Job-EJYKMG |             .NET 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.8 ms |  33.00 ms |  1.81 ms |         - |         - |        - |     18 KB |
    | 'ImageSharp Lossless Webp' | Job-EJYKMG |             .NET 5.0 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   313.9 ms |  69.97 ms |  3.84 ms | 5000.0000 | 1500.0000 | 500.0000 | 22,862 KB |
    |        'Magick Lossy Webp' | Job-BMMSCS |        .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   106.0 ms |   6.18 ms |  0.34 ms |         - |         - |        - |     25 KB |
    |    'ImageSharp Lossy Webp' | Job-BMMSCS |        .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   759.4 ms |  91.77 ms |  5.03 ms |         - |         - |        - |  2,769 KB |
    |     'Magick Lossless Webp' | Job-BMMSCS |        .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.9 ms |  16.58 ms |  0.91 ms |         - |         - |        - |     15 KB |
    | 'ImageSharp Lossless Webp' | Job-BMMSCS |        .NET Core 3.1 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   491.0 ms |  47.61 ms |  2.61 ms | 4000.0000 | 1000.0000 |        - | 22,860 KB |
    |        'Magick Lossy Webp' | Job-HVJOCM | .NET Framework 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.2 ms |  14.95 ms |  0.82 ms |         - |         - |        - |     32 KB |
    |    'ImageSharp Lossy Webp' | Job-HVJOCM | .NET Framework 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,135.7 ms | 117.43 ms |  6.44 ms |         - |         - |        - |  2,780 KB |
    |     'Magick Lossless Webp' | Job-HVJOCM | .NET Framework 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.2 ms |  17.90 ms |  0.98 ms |         - |         - |        - |     18 KB |
    | 'ImageSharp Lossless Webp' | Job-HVJOCM | .NET Framework 4.7.2 | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,773.9 ms | 169.72 ms |  9.30 ms | 4000.0000 | 1000.0000 |        - | 30,557 KB |
    

    The biggest deviation to the original benchmarks from this thread is lossy encoding. The good news is though, I made good progress in improving that (see the open PR and there is more potential there).

  14. brianpopow commented on Nov 10, 2021

    @brianpopow
    Collaborator

    I wanted to share some updates on the improvements for webp.
    Benchmarks from the current master branch:

    Encode:

    BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1320 (21H1/May2021Update)
    Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
    .NET SDK=6.0.100
      [Host]     : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT
      Job-EIDTBY : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT
      Job-CPHHDA : .NET Core 3.1.21 (CoreCLR 4.700.21.51404, CoreFX 4.700.21.51508), X64 RyuJIT
      Job-UGXIBH : .NET Framework 4.8 (4.8.4420.0), X64 RyuJIT
    
    IterationCount=3  LaunchCount=1  WarmupCount=3
    
    |                     Method |        Job |              Runtime |             Arguments |    TestImage |      Mean |     Error |   StdDev | Ratio |     Gen 0 |     Gen 1 |     Gen 2 | Allocated |
    |--------------------------- |----------- |--------------------- |---------------------- |------------- |----------:|----------:|---------:|------:|----------:|----------:|----------:|----------:|
    |        'Magick Webp Lossy' | Job-EIDTBY |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png |  23.25 ms |  0.356 ms | 0.020 ms |  0.14 |         - |         - |         - |     67 KB |
    |    'ImageSharp Webp Lossy' | Job-EIDTBY |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 133.63 ms |  7.292 ms | 0.400 ms |  0.83 | 4000.0000 |  250.0000 |         - | 16,648 KB |
    |     'Magick Webp Lossless' | Job-EIDTBY |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 160.69 ms | 14.893 ms | 0.816 ms |  1.00 |         - |         - |         - |    518 KB |
    | 'ImageSharp Webp Lossless' | Job-EIDTBY |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 288.44 ms |  6.384 ms | 0.350 ms |  1.80 | 8000.0000 | 3000.0000 |  500.0000 | 61,553 KB |
    |                            |            |                      |                       |              |           |           |          |       |           |           |           |           |
    |        'Magick Webp Lossy' | Job-CPHHDA |        .NET Core 3.1 |               Default | Png/Bike.png |  23.24 ms |  2.965 ms | 0.163 ms |  0.15 |         - |         - |         - |     67 KB |
    |    'ImageSharp Webp Lossy' | Job-CPHHDA |        .NET Core 3.1 |               Default | Png/Bike.png | 147.15 ms |  5.399 ms | 0.296 ms |  0.92 | 4000.0000 |         - |         - | 16,648 KB |
    |     'Magick Webp Lossless' | Job-CPHHDA |        .NET Core 3.1 |               Default | Png/Bike.png | 159.59 ms |  4.746 ms | 0.260 ms |  1.00 |         - |         - |         - |    517 KB |
    | 'ImageSharp Webp Lossless' | Job-CPHHDA |        .NET Core 3.1 |               Default | Png/Bike.png | 310.73 ms | 20.905 ms | 1.146 ms |  1.95 | 8000.0000 | 3000.0000 | 1000.0000 | 61,555 KB |
    |                            |            |                      |                       |              |           |           |          |       |           |           |           |           |
    |        'Magick Webp Lossy' | Job-UGXIBH | .NET Framework 4.7.2 |               Default | Png/Bike.png |  23.40 ms |  0.566 ms | 0.031 ms |  0.15 |         - |         - |         - |     68 KB |
    |    'ImageSharp Webp Lossy' | Job-UGXIBH | .NET Framework 4.7.2 |               Default | Png/Bike.png | 439.02 ms | 35.185 ms | 1.929 ms |  2.74 | 4000.0000 |         - |         - | 16,752 KB |
    |     'Magick Webp Lossless' | Job-UGXIBH | .NET Framework 4.7.2 |               Default | Png/Bike.png | 159.98 ms |  9.306 ms | 0.510 ms |  1.00 |         - |         - |         - |    518 KB |
    | 'ImageSharp Webp Lossless' | Job-UGXIBH | .NET Framework 4.7.2 |               Default | Png/Bike.png | 430.20 ms | 35.086 ms | 1.923 ms |  2.69 | 8000.0000 | 3000.0000 | 1000.0000 | 61,698 KB |
    

    Decode:

    IterationCount=3  LaunchCount=1  WarmupCount=3
    
    |                     Method |        Job |              Runtime |             Arguments |        TestImageLossy |        TestImageLossless |       Mean |    Error |  StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
    |--------------------------- |----------- |--------------------- |---------------------- |---------------------- |------------------------- |-----------:|---------:|--------:|------:|------:|------:|----------:|
    |        'Magick Lossy Webp' | Job-JFZHJM |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.2 ms | 22.09 ms | 1.21 ms |     - |     - |     - |     25 KB |
    |    'ImageSharp Lossy Webp' | Job-JFZHJM |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   275.7 ms |  9.75 ms | 0.53 ms |     - |     - |     - |  1,703 KB |
    |     'Magick Lossless Webp' | Job-JFZHJM |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   106.8 ms |  8.18 ms | 0.45 ms |     - |     - |     - |     16 KB |
    | 'ImageSharp Lossless Webp' | Job-JFZHJM |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   261.8 ms | 56.62 ms | 3.10 ms |     - |     - |     - |  2,051 KB |
    |        'Magick Lossy Webp' | Job-LPYOLC |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   107.6 ms |  6.76 ms | 0.37 ms |     - |     - |     - |     25 KB |
    |    'ImageSharp Lossy Webp' | Job-LPYOLC |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   293.4 ms | 10.52 ms | 0.58 ms |     - |     - |     - |  1,702 KB |
    |     'Magick Lossless Webp' | Job-LPYOLC |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   106.6 ms | 13.72 ms | 0.75 ms |     - |     - |     - |     15 KB |
    | 'ImageSharp Lossless Webp' | Job-LPYOLC |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   437.4 ms | 58.98 ms | 3.23 ms |     - |     - |     - |  2,049 KB |
    |        'Magick Lossy Webp' | Job-GQRTJY | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   106.8 ms |  8.77 ms | 0.48 ms |     - |     - |     - |     32 KB |
    |    'ImageSharp Lossy Webp' | Job-GQRTJY | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   565.5 ms | 23.85 ms | 1.31 ms |     - |     - |     - |  1,708 KB |
    |     'Magick Lossless Webp' | Job-GQRTJY | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp |   106.7 ms |  5.65 ms | 0.31 ms |     - |     - |     - |     18 KB |
    | 'ImageSharp Lossless Webp' | Job-GQRTJY | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,768.8 ms | 94.91 ms | 5.20 ms |     - |     - |     - |  9,689 KB |
    

    Notable mentions:

    • Lossy encoding is down from 258 ms to 134 ms
    • Lossy decoding is down from 669 ms to 276 ms
    • Memory allocations is much better for encoding.

    Notes:

    • Lossy encoding can be further improved with hardware intrinsics (ITransform, FTransform are main candidates).
    • Lossy decoding takes alot of time converting data from YUV (30% time). This can also profit alot from hardware intrinsics.
      Its pretty complicated though. I am not sure if i can port that over from libwebp. Maybe someone with more experience SSE2/SSE4 is needed here.
    • While the lower memory allocations is nice, it was mainly achieved by reusing objects instead of creating them. This comes at the cost of having them
      cleared before using them. From profiling i would roughly guess this costs 5% performance. I still think its worth it.
  15. CarlosTorrecillas commented on Nov 22, 2021

    @CarlosTorrecillas

    Is that already available in the latest package? If so, I somehow get the UnknownImageFormatException and WEBP is still not listed there. Perhaps I'm doing something wrong but I'm not able to load a WEBP image just yet.

  16. JimBobSquarePants commented on Nov 22, 2021

    @JimBobSquarePants
    MemberAuthor

    You need to use the MyGet feed. We’ll be shipping it to NuGet with 2.0

  17. brianpopow commented on Dec 21, 2021

    @brianpopow
    Collaborator

    Some update in the current status.
    Here are the benchmark results from the current master branch:

    Encode:

    |                     Method |        Job |              Runtime |             Arguments |    TestImage |      Mean |     Error |   StdDev | Ratio | RatioSD |     Gen 0 |     Gen 1 |     Gen 2 | Allocated |
    |--------------------------- |----------- |--------------------- |---------------------- |------------- |----------:|----------:|---------:|------:|--------:|----------:|----------:|----------:|----------:|
    |        'Magick Webp Lossy' | Job-OLZPMB |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png |  23.25 ms |  0.128 ms | 0.076 ms |  0.15 |    0.00 |         - |         - |         - |     67 KB |
    |    'ImageSharp Webp Lossy' | Job-OLZPMB |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png |  94.60 ms |  0.788 ms | 0.469 ms |  0.59 |    0.00 | 4166.6667 |  166.6667 |         - | 17,588 KB |
    |     'Magick Webp Lossless' | Job-OLZPMB |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 160.34 ms |  0.974 ms | 0.579 ms |  1.00 |    0.00 |         - |         - |         - |    518 KB |
    | 'ImageSharp Webp Lossless' | Job-OLZPMB |             .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 272.89 ms | 15.251 ms | 9.076 ms |  1.70 |    0.06 | 7500.0000 | 3500.0000 | 1500.0000 | 46,979 KB |
    |                            |            |                      |                       |              |           |           |          |       |         |           |           |           |           |
    |        'Magick Webp Lossy' | Job-MHFYZF |        .NET Core 3.1 |               Default | Png/Bike.png |  23.34 ms |  0.303 ms | 0.180 ms |  0.15 |    0.00 |         - |         - |         - |     67 KB |
    |    'ImageSharp Webp Lossy' | Job-MHFYZF |        .NET Core 3.1 |               Default | Png/Bike.png | 110.29 ms |  2.185 ms | 1.300 ms |  0.69 |    0.01 | 4000.0000 |         - |         - | 17,588 KB |
    |     'Magick Webp Lossless' | Job-MHFYZF |        .NET Core 3.1 |               Default | Png/Bike.png | 159.52 ms |  0.650 ms | 0.387 ms |  1.00 |    0.00 |         - |         - |         - |    517 KB |
    | 'ImageSharp Webp Lossless' | Job-MHFYZF |        .NET Core 3.1 |               Default | Png/Bike.png | 277.31 ms |  7.406 ms | 4.407 ms |  1.74 |    0.03 | 8000.0000 | 4000.0000 | 2000.0000 | 46,981 KB |
    |                            |            |                      |                       |              |           |           |          |       |         |           |           |           |           |
    |        'Magick Webp Lossy' | Job-PATHPQ | .NET Framework 4.7.2 |               Default | Png/Bike.png |  23.31 ms |  0.237 ms | 0.141 ms |  0.15 |    0.00 |         - |         - |         - |     68 KB |
    |    'ImageSharp Webp Lossy' | Job-PATHPQ | .NET Framework 4.7.2 |               Default | Png/Bike.png | 431.98 ms |  2.513 ms | 1.496 ms |  2.71 |    0.01 | 4000.0000 |         - |         - | 17,642 KB |
    |     'Magick Webp Lossless' | Job-PATHPQ | .NET Framework 4.7.2 |               Default | Png/Bike.png | 159.66 ms |  0.931 ms | 0.554 ms |  1.00 |    0.00 |         - |         - |         - |    518 KB |
    | 'ImageSharp Webp Lossless' | Job-PATHPQ | .NET Framework 4.7.2 |               Default | Png/Bike.png | 451.57 ms |  1.993 ms | 1.186 ms |  2.83 |    0.01 | 8000.0000 | 4000.0000 | 2000.0000 | 47,107 KB |
    

    Decode:

    |                     Method |        Job |              Runtime |             Arguments |        TestImageLossy |        TestImageLossless |     Mean |   Error |  StdDev |     Gen 0 |     Gen 1 |     Gen 2 | Allocated |
    |--------------------------- |----------- |--------------------- |---------------------- |---------------------- |------------------------- |---------:|--------:|--------:|----------:|----------:|----------:|----------:|
    |        'Magick Lossy Webp' | Job-EBSHHU |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 105.6 ms | 2.48 ms | 1.48 ms |         - |         - |         - |     16 KB |
    |    'ImageSharp Lossy Webp' | Job-EBSHHU |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 194.0 ms | 2.80 ms | 1.67 ms | 2000.0000 | 2000.0000 | 2000.0000 |  1,765 KB |
    |     'Magick Lossless Webp' | Job-EBSHHU |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 105.4 ms | 1.67 ms | 0.99 ms |         - |         - |         - |     16 KB |
    | 'ImageSharp Lossless Webp' | Job-EBSHHU |             .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 238.9 ms | 1.35 ms | 0.80 ms | 2000.0000 | 2000.0000 | 2000.0000 |  1,754 KB |
    |        'Magick Lossy Webp' | Job-ACMKPP |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 106.1 ms | 2.55 ms | 1.51 ms |         - |         - |         - |     15 KB |
    |    'ImageSharp Lossy Webp' | Job-ACMKPP |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 204.5 ms | 2.10 ms | 1.25 ms | 1000.0000 |         - |         - |  1,755 KB |
    |     'Magick Lossless Webp' | Job-ACMKPP |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 105.8 ms | 0.65 ms | 0.39 ms |         - |         - |         - |     15 KB |
    | 'ImageSharp Lossless Webp' | Job-ACMKPP |        .NET Core 3.1 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 241.2 ms | 4.31 ms | 2.57 ms | 1000.0000 |         - |         - |  1,736 KB |
    |        'Magick Lossy Webp' | Job-POKFWI | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 105.9 ms | 2.03 ms | 1.21 ms |         - |         - |         - |     18 KB |
    |    'ImageSharp Lossy Webp' | Job-POKFWI | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 555.2 ms | 5.17 ms | 3.08 ms | 1000.0000 |         - |         - |  1,772 KB |
    |     'Magick Lossless Webp' | Job-POKFWI | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 105.8 ms | 1.30 ms | 0.78 ms |         - |         - |         - |     18 KB |
    | 'ImageSharp Lossless Webp' | Job-POKFWI | .NET Framework 4.7.2 |               Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 548.0 ms | 5.33 ms | 3.17 ms | 1000.0000 |         - |         - |  9,377 KB |
    

    Notable mentions:

    • Lossy encoding is down from 133.63 ms to 94.60 ms
    • Lossy decoding is down from 276 ms to 194.0 ms
    • Lossless decoding is down from 262 ms to 238.9 ms
  18. antonfirsov commented on Feb 6, 2022

    @antonfirsov
    Member

    Is this general issue still valuable? = meaning shall we roll it to "Future", or close it?

  19. brianpopow commented on Feb 6, 2022

    @brianpopow
    Collaborator

    Since I do not see any big opportunities anymore to improve the performance further, I would vote for closing the issue.

  20. JimBobSquarePants commented on Feb 6, 2022

    @JimBobSquarePants
    MemberAuthor

    Yeah let's close it for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions