I recently released SSTiles, a map tile maker which used ImageMagick (using Imagick) or GD to generate tiles. It worked great locally, but when I uploaded it to my shared hosting provider I found that the Imagick module wasn’t enabled.
When I started looking into how to enable it, I found out that I had several other options, so I decided to implement the tile creation algorithm using each of the libraries and benchmark them. You can check out the code on GitHub, and below you’ll find the results.
- Imagick (ImageMagick)
- MagickWand (ImageMagick too)
- convert (ImageMagick command-line binary)
- GraphicsMagick (a fork from ImageMagick).
The Testing Setup
The machine was a ThinkPad W530 with 32 Gigs of RAM and an Intel i7-3610QM CPU at 2.30GHz. It has a 5400rpm hard drive.
I’m running Debian Jessie, with the Linux 3.10-3-amd64 kernel. The server software was Apache 2.4.6 and PHP 5.5.4.
I ran 1000 tile create operations with each of the contenders. Each iteration does the following algorithm:
- Determine the dimensions of the source image.
- Determine the number of tiles in the requested slippy map zoom leve.
- Crop the specified tile out of the source image.
- If the tile is not square, stretch it to the appropriate dimensions.
- Write the image to a cache file.
- Print the image to the browser.
For a different server configuration or a different set of operations a different library may be faster or use less memory.
Using the ImageMagick command line tools (convert and identify) via shell_exec (or backticks) was both the fastest and the slowest method of generating thumbnails. It trended heavily towards the faster end of the spectrum though.
GD was the most consistent image library, having both least variation between tile creation rounds.
Here’s a chart showing the fastest, average and slowest run for each function. Each function was called 1000 times, and each function created the same set of 1000 tiles.
You can also see the breakdown for each method as visualized by KCachegrind. I added the red bars to show where each method is divided. It seems that in all cases reading the image is what takes the most time.
I’m not 100% sure how to interpret these XHProf memory usage results. There are two columns in the output tables: Inclusive Memory Usage and Inclusive Peak Memory Usage. I tried asking on Reddit but got no answer. I assume that someone will come along here at some point and tell me that I missed some obvious documentation somewhere.
At the moment I believe that Inclusive Memory Usage is memory managed by PHP, while Inclusive Peak Memory Usage is total memory used. This is especially important on shared hosting environments where the PHP memory limit is low but the shell memory doesn’t count.
In any case, less memory used is better so let’s take a look.
|Incl Mem Use (bytes)||21032||13592||144080||176296||7216|
|Incl Peak Mem Use (bytes)||22728||22920||5024||12296||28152|
In my use case the tiles only need to get generated once (due to caching), but that generation needs to work without running out of memory. Since SSTiles automatically picks which method to use to create tiles, I’ve ordered those checks by which uses the least memory (Inclusive Memory Usage).