As the first bit of experimentation for my masters project, I wrote a tile server for Google Maps. Basically, Maps works by downloading small (256×256px) “tiles” of the map as you drag around (this is why if you drag fast you see it appear in squares). You can use the Google Maps API to really easily overlay or entirely replace the default map with your own imagery, just by making a program which generates these small images.
As part of my project, I may be drawing images over the map, so decided to try out map tile generation to see if it is feasible. I needed an image that I could draw sections of independently of the rest of the image, and zoom in to great detail – fractals! The classic Mandelbrot set was the obvious choice, so I found a Processing example, tweaked it a bit, and wrote a Java Servlet which used Processing as a back-end to draw the map tiles. This worked incredibly well (after dealing with some issues with Processing not being thread-safe), and within an hour or two of conception had a fully working version. I showed this off in my tutor meeting, but due to my rubbish home broadband it was taking upwards of a minute to load a screenful.
I then decided to “grow up” the implementation, rewriting it in PHP and putting it on this site. Initially this worked fine (after adding caching for the tiles) but very quickly brought the server to a standstill, as fractals are pretty hefty calculations, and one person visiting the site would request ~30 of them just by going to the web page. I adapted some optimised code from The Computer Language Benchmarks Game but this didn’t help much, as the code wasn’t too bad already!
My next idea was to pre-generate all the tiles on my machine, and upload these to the web host – this way, the web server would only need to generate tiles if the user zoomed in too far. I hacked the servlet into a standalone app; removing Processing and instead using the javax.imageio classes to directly write PNGs, using 4 threads and pumping out tiles as fast as possible. I left this running for a couple days, creating about 25GB of tiles, uploading them to the web server as I went along.
I played with this new ultra-snappy version for a while, but realised that the interesting part of fractals is the ability to zoom in to infinite detail – panning around is all well and good but as soon as you zoomed too far the server went horribly slow again. At this point, I only really had one option left – rewrite the tile generation in C. I ported over the Java code to calculate the fractal, and used libpng to write out the images. Surprisingly quickly I had a C version (I didn’t bother with threading as this is a headache in C), which, after a bit of benchmarking, turned out to be massively faster than both the Java and PHP versions. Before people jump on that as “LOL JAVA IS SLOW!!1”, the language benchmarks I took the code from show Java as only slightly slower than C – I think the bottleneck was in fact in writing out the PNG, as I was (accidentally) using the OpenJDK implementation which is not known for its speed!
Anyway, with this new C version I started pre-generating tiles at lightening speed, when on a hunch decided to change the PHP code to simply run the C executable to generate the tiles. Trying it out, I was amazed. I even had to do a quick check to make sure it wasn’t still serving cached tiles and was in fact generating them on-the-fly.
So there you have it! I’ve just realised I’ve written that huge essay and not provided a link to the hyper-optimized, super-fast, Google Maps Mandelbrot!
Source code to all of this available on request; I plan to tidy it up and release it on here some time soon as well.











