RFR: 8374377: PNGImageDecoder Slow For 8-bit PNGs

Jeremy Wood jwood at openjdk.org
Mon Dec 29 03:06:56 UTC 2025


On Sun, 28 Dec 2025 17:36:51 GMT, Daniel Gredler <dgredler at openjdk.org> wrote:

>> When decoding an uninterlaced 8-bit PNG image, the PNGImageDecoder is basically copying one byte at a time.
>> 
>> This PR uses System.arraycopy instead, and it shows approx a 10% improvement.
>> 
>> This graph shows the time it takes different decoders to convert a byte array into a BufferedImage as the size of the PNG image increases:
>> 
>> <img width="596" height="366" alt="Screenshot 2025-12-27 at 9 14 19 PM" src="https://github.com/user-attachments/assets/73583cb2-eda0-47a8-b818-735a1835f1e8" />
>> 
>> (This originally came to my attention when looking at an image in Java 1.8. There the ImageConsumer model took approx 400% longer than ImageIO. I was happy to see in recent JDKs that gap narrowed significantly, but there was still a noticeable 10% discrepancy.)
>> 
>> I haven't tried submitting a performance enhancement PR before; I'm not sure if this issue meets this group's threshold for being worth addressing. And if it does: I'm not sure how to structure a unit test for it.
>
> Do you have a JMH test for the attached graph that can be used to replicate locally? If you've not used JMH before, or haven't used it in the context of OpenJDK, you can check existing performance tests in the `test/micro` directory, or see this example (not part of OpenJDK, just something I've used in the past to test things locally): https://gist.github.com/gredler/e8ff9d52440cd103cd5b7766defff5b8

@gredler Thanks. I'm not familiar with JMH.

I used your example (and a lot of googling) to set up a basic benchmark that is now attached to this ticket.

For a 2500x2500 px image, the time on my Mac went from approx 25.296 to 22.132.

Is there any interest in me:
A. Creating a graph as the image dimensions change?
B. Contrasting this implementation against ImageIO?

I'm not sure what the long-term usage of this benchmark .java would be. If this PR is accepted: the slower "before" time will be not be relevant to anyone going forward.

And the most important question (IMO): is there enough interest in this group to review/accept this proposal? (If not: I can stop spending time on it.)

## Before this PR

Benchmark                                                 Mode  Cnt   Score   Error  Units
PNGImageDecoder_8bit_uninterlaced.measurePNGImageDecoder  avgt   15  25.296 ± 0.521  ms/op

## After this PR

Benchmark                                                 Mode  Cnt   Score   Error  Units
PNGImageDecoder_8bit_uninterlaced.measurePNGImageDecoder  avgt   15  22.132 ± 0.378  ms/op

-------------

PR Comment: https://git.openjdk.org/jdk/pull/29004#issuecomment-3695319015


More information about the client-libs-dev mailing list