Open manticore-projects opened 10 months ago
Thanks for doing this comparison! Please keep me posted as you have more benchmarks :)
On Wed, 15 Nov 2023 at 07:58, manticore-projects @.***> wrote:
Greetings!
Thank you and compliments for this great library. I wrapped it into a Java Library pursuing for the fastest PNG Encoder. Please see https://github.com/manticore-projects/fpng-java
As it looks by now, FPNGE is the winner by size and also performance:
Benchmark (imageName) Mode Cnt Score Error Units FPNGEBenchmark.encode example.png avgt 3 5.895 ± 0.369 ms/op FPNGEBenchmark.encode looklet-look-scale6.png avgt 3 242.326 ± 3.215 ms/op FPNGEncoderBenchmark.encode example.png avgt 3 7.267 ± 4.725 ms/op FPNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 353.969 ± 14.833 ms/op ImageIOEncoderBenchmark.encode example.png avgt 3 54.096 ± 0.742 ms/op ImageIOEncoderBenchmark.encode looklet-look-scale6.png avgt 3 1285.791 ± 14.237 ms/op ObjectPlanetPNGEncoderBenchmark.encode example.png avgt 3 25.882 ± 0.670 ms/op ObjectPlanetPNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 639.232 ± 23.186 ms/op PNGEncoderBenchmark.encode example.png avgt 3 29.218 ± 0.965 ms/op PNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 573.997 ± 16.234 ms/op PNGEncoderBenchmark.encodeFastest example.png avgt 3 17.628 ± 0.511 ms/op PNGEncoderBenchmark.encodeFastest looklet-look-scale6.png avgt 3 362.208 ± 4.346 ms/op
Although I still need to improve those Benchmarks so they compare based on similar achieved file-sizes and also need to reflect different JDKs.
— Reply to this email directly, view it on GitHub https://github.com/veluca93/fpnge/issues/27, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOPAIZ755CKC6ZPGPRF6OLYERRZZAVCNFSM6AAAAAA7L75NTCVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE4TIMJWGQ3TAMA . You are receiving this because you are subscribed to this thread.Message ID: @.***>
I am glad that you like it.
One thing: The pure Java PNG Encoder (last entry in the list) supports a "Parallel/Multi-Core" mode which is blazing fast, especially for large pictures.
For obvious reasons, it outperforms even FPNGE (when many free cores/threads are available):
PNGEncoderBenchmark.encode example.png avgt 3 5.587 ± 0.882 ms/op
PNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 92.921 ± 11.868 ms/op
PNGEncoderBenchmark.encodeFastest example.png avgt 3 3.694 ± 0.868 ms/op
PNGEncoderBenchmark.encodeFastest looklet-look-scale6.png avgt 3 90.635 ± 21.768 ms/op
Is there a chance to add a multi threaded mode to FPNGE?
It is certainly possible (for example, by splitting the image in multiple stripes and encoding each stripe separately), although I am not sure I will have time to dedicate to this in the near future...
On Wed, 15 Nov 2023 at 10:45, manticore-projects @.***> wrote:
I am glad that you like it.
One thing: The pure Java PNG Encoder https://github.com/pngencoder/pngencoder (last entry in the list) supports a "Parallel/Multi-Core" mode which is blazing fast, especially for large pictures.
For obvious reasons, it outperforms even FPNGE (when many free cores/threads are available):
PNGEncoderBenchmark.encode example.png avgt 3 5.587 ± 0.882 ms/op PNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 92.921 ± 11.868 ms/op PNGEncoderBenchmark.encodeFastest example.png avgt 3 3.694 ± 0.868 ms/op PNGEncoderBenchmark.encodeFastest looklet-look-scale6.png avgt 3 90.635 ± 21.768 ms/op
Is there a chance to add a multi threaded mode to FPNGE?
— Reply to this email directly, view it on GitHub https://github.com/veluca93/fpnge/issues/27#issuecomment-1812119202, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOPAI6QD35FSBOV7QEZAXTYESFNJAVCNFSM6AAAAAA7L75NTCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJSGEYTSMRQGI . You are receiving this because you commented.Message ID: @.***>
No problem at all. My usecase is specifically on "many smaller PNGs" (like a kind of screen recording), so I don't need the multi-threaded mode.
I just wanted to point out, that FPNGE
is not under all circumstances the fastest.
I have replaced the slow/bad/expensive Java 4Byte ABGR to RGBA translation with SSE bit shuffling calls. (AVX was slower, likely due to the 32 bit alignment requirement).
Now, FPNGE Java is undisputed, encoding a 28MB Image withing 182 ms is just awesome.
GRAALVM 11
Benchmark (imageName) Mode Cnt Score Error Units
FPNGEBenchmark.encode example.png avgt 3 2.731 ± 0.018 ms/op
FPNGEBenchmark.encode looklet-look-scale6.png avgt 3 182.363 ± 159.723 ms/op
FPNGEncoderBenchmark.encode example.png avgt 3 6.491 ± 0.526 ms/op
FPNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 313.017 ± 71.408 ms/op
ImageIOEncoderBenchmark.encode example.png avgt 3 47.353 ± 3.971 ms/op
ImageIOEncoderBenchmark.encode looklet-look-scale6.png avgt 3 1199.796 ± 47.642 ms/op
ObjectPlanetPNGEncoderBenchmark.encode example.png avgt 3 28.079 ± 0.101 ms/op
ObjectPlanetPNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 660.480 ± 79.759 ms/op
PNGEncoderBenchmark.encode example.png avgt 3 29.172 ± 0.288 ms/op
PNGEncoderBenchmark.encode looklet-look-scale6.png avgt 3 574.485 ± 16.903 ms/op
PNGEncoderBenchmark.encodeFastest example.png avgt 3 17.516 ± 0.135 ms/op
PNGEncoderBenchmark.encodeFastest looklet-look-scale6.png avgt 3 360.417 ± 8.995 ms/op
Greetings! We have just released FPNG-JAVA stable version 1.1.0 with binaries for Windows, Linux and MacOS.
I had to add some Macros for getting the Windows DLL work.
Please try it and let us know about your benchmarks. Thank you a lot and cheers!
Question please:
For "small" size PNGs, the FPNGe encoded size is very competitive, especially when considering the huge performance gain. Of course, with the other encoders even smaller encodings are possible, but that would come with much worse performance.
However, for large size PNGs, there seem to be a material penalty in encoded size. Almost 70% larger than ImageIO. Is that expected an explainable by design? If so, what is the expected "sweet spot" where compression rates fall off? What is the reason that compression gets worse for the large image?
For this benchmark, Compression Level = 5
has been set.
That depends a lot on the specific image, could I see what images you are compressing here?
That depends a lot on the specific image, could I see what images you are compressing here?
Yes, of course, Its all in the Repo, sub project benchmark: https://github.com/manticore-projects/fpng-java/tree/main/benchmark/src/test/resources If Java is not too much of a burden for you, you can just run the benchmarks, its all included and "./gradlew jmh" should work out of the box.
What I find most weird is Standard Java ImageIO
. It does not provide any switches, just encode and that's it.
So how come that it score so well by size on the large picture, although it does not well in terms of size on the small picture.
I feel like compression is not working for FPNG/FPNGe on the large picture and I wonder why.
So how come that it score so well by size on the large picture, although it does not well in terms of size on the small picture
I don't think a sample size of one is enough to justify that conclusion.
Perhaps LZ77 is more effective on your larger image (fpnge only does RLE, and in limited cases; I see a lot of the same colour in that image, so maybe fpnge's RLE isn't triggered optimally). fpnge takes some shortcuts compared to traditional PNG encoders to achieve its speed, which means that the compression loss can vary depending on how well the image suits the model fpnge takes.
Thank you for this explanation. Fair point raised, I will need to add more tests.
Greetings!
Thank you and compliments for this great library. I wrapped it into a Java Library pursuing for the fastest PNG Encoder. Please see https://github.com/manticore-projects/fpng-java
As it looks by now, FPNGE is the winner by size and also performance:
Although I still need to improve those Benchmarks so they compare based on similar achieved file-sizes and also need to reflect different JDKs.