Render a mandelbrot and serve it over HTTP. Archive of homework assignment for BSc.
Removes a file that doesn't even make sense anymore...
words are hard
gpl'd

heads

tip
browse log

clone

read-only
https://hg.sr.ht/~sqwishy/mandelbro
read/write
ssh://hg@hg.sr.ht/~sqwishy/mandelbro

Mandelbro

This repository is a historical record of a project I did as a homework assignment. It's not really meant to be used for anything.

Wat

In university I felt everyone should implement a mandelbro algorithm at least once before they graduate. So this was mine. It uses assembly, C, and Cython to create a Python module which can render mandelbrots, and Python to serve them over HTTP.

History

During my Fall semester in 2011 at university, for Computing 242 Machine Languages, I wrote a python script to generate a mandelbrot using PIL and served it using Bottle. The crux of the lab is a bit where I wrote part of the mandelbrot generation code in assembly in order to improve performance.

In the following semester, I looked into porting my code from Python into C. However, I ran into a problem and I gave up for a few months before deciding to use Cython, instead of C, to improve performance. Initially, I switched to Python 3 for this. However, I found that this was a huge hindrance on speed, and switched back to 2.7. This was a successful and very rewarding experience. Rendering (and encoding to a PNG) an 800×600 (480,000 pixels) image took 3.33 seconds in pure python after optimizations and 0.285 seconds after being ported to Cython.

Unfortunately, this performance did not persist when I tried accessing it from the web interface. In that case, images took one to two seconds to render. I determined that this was because my code was fighting with Bottle for the GIL, which my code needed every time it wanted to mutate the image. There were a number of solutions to this, but I thought the coolest one was to completely remove the requirement of acquiring the GIL while rendering. So I ported it to C, using Cython to wrap the function, and opencv to encode the image. This was challenging; but, in the end, the function could create the 800×600 rendering in 0.113 seconds. The coolest part was that the responsiveness of the web interface was hugely improved. According to my measurements of the request times with firebug, where the Cython implementation took 1170ms to serve an image, the C implementation takes 135ms.

The quality of the lab isn’t perfect. I was somewhat rushed (mostly the HTML and JavaScript) and I was new to some of the parts I was dealing with. However, I enjoyed it very much and, in the end, I was proud of what I produced — especially since most of my success was a result of independent initiative.