mfiano's blog

Optimizing Common Lisp's png-read Library

August 7, 2017

2 minute read


After many years frustrated with how slow Common Lisp's png-read library is, I decided to take an evening to try to optimize it. Here are the timing results of trying to parse a file from disk 1000 times with SBCL 1.3.19, for each of these sample images in PNGSuite.

Grayscale 1bit0.190s0.117s1.62x
Grayscale 2bit0.117s0.077s1.52x
Grayscale 4bit0.119s0.094s1.27x
Grayscale 8bit0.201s0.118s1.70x
Grayscale 16bit0.287s0.203s1.41x
Grayscale/Alpha 8bit0.426s0.191s2.23x
Grayscale/Alpha 16bit0.946s0.559s1.69x
Indexed 1bit0.202s0.163s1.24x
Indexed 2bit0.217s0.187s1.16x
Indexed 4bit0.221s0.199s1.11x
Indexed 8bit0.267s0.265s1.01x
RGB 8bit0.765s0.283s2.70x
RGB 16bit1.291s0.453s2.85x
RGBA 8bit1.035s0.335s3.09x
RGBA 16bit1.848s0.722s2.56x

Particularly noticeable are the RGB and RGBA variants, with an approximate 3x boost. I may continue to optimize more, but for a start I am definitely happier.

Update 2017-08-07: Changes have been merged upstream, so everyone can take advantage of the performance boost in the original version later this month when the latest Quicklisp dist is released.

Update 2017-08-24: I wrote a PNG parser completely from scratch, called pngload, that is even faster, and more featureful. Check it out here.

© Michael Fiano. Last modified: September 04, 2022. Website built with Franklin.jl.