I've recently done a performance comparison between Go's image package and
Python Imaging Library by porting a simple Python script that reads an RGBA
image from PNG and converts it to grayscale.
PIL provides a higher level interface than Go's image package. In Python,
the conversion is performed like this:
image = Image.open(filename)
assert image.mode == 'RGBA'
new_image = image.convert('L')
In Go, I tried two alternative approaches:
1) use image/draw.Draw()
2) copy each pixel value in a loop
Here's a glimpse at the timings:
$ python to_grayscale.py
Image open took 2.87699699402 ms
Converting the image took 3.58319282532 ms
Image save took 24.7330665588 ms
Total time: 31.1932563782 ms
$ go run to_grayscale.go
Image decode took 17 ms
Creating an empty image took 0 ms
Converting pixels took 21 ms
Image save took 31 ms
Total time: 69 ms
So far, the timings Go is showing are worse than I expected. Here's a repo
with the code for both versions and a test image ->
Is there a more performant way to do this in Go? I should say that the
package docs lack in examples badly. There was a post about image/draw,
in it they also used the Draw function from image/draw.
I'm not sure if Python's time() function offers enough precision (under OS
X), but it's the best one I've found.
On a side note, there's been another thread on the list where it turned
out that image/png could be optimized quite easily, but no one had bothered
to do this before.
I'm curious to hear your opinions about practicability of repeating the
develop-debug-optimize cycle all over again for the functionality that
already exists in other languages. PIL has been around since 1995, its
authors had plenty of time to optimize it and implement most of the
commonly used features. And for PNG decoding there's libpng and other more
recent libraries. Both are written in C and have been field-tested for
What's the reasoning behing reimplementing this in Go. Language purity?
Security? I'll be happy to hear your opinions, guys.