When I started learning Swift, I revisited the Mandelbrot Set. It’s an old favorite of mine because it is so simple to compute some rather nice images.
The above image was computed using Swift with the vDSP library in the Accelerate Framework and Grand Central Dispatch. Keeping track of interior values allowed me to color the interior as well as the exterior.
Back in June of 2013, I wrote a very simple C program to compute the Mandelbrot Set and display it in a different way. It produced the following image.
The C code was very simple and single threaded. This is a run from the shell using the time utility.
Triton:Desktop david$ time ./Orbitals Computing row 2880 of 2880 Done! Return code = 0 real 0m37.342s user 0m37.202s sys 0m0.090s
Each pixel in the set is iterated 4000 times. The complex values are mapped onto the complex plane with the upper left corner being (-2.0, 2.0) and the lower right corner being (2.0, -2.0). The image was originally generated in TARGA format using some code I scraped off the Internet. I converted it to PNG using Preview so that browsers can view it. For some reason, the code flips the image horizontally. I haven’t taken the trouble to debug it.
I also wanted to try a comparison of Swift to C for this computation. I should have gone for a pure transliteration so that I could get a valid speed comparison. But I didn’t. The Swift version does a few things the C version does not do. One is dynamic memory allocation for the computed values. Another is an abstraction of complex number arithmetic. The last is adding Grand Central Dispatch in an attempt to get more speed.
The dynamic memory allocation turned out to be a major performance killer.
The run time:
Triton:Desktop david$ time ./SwiftOrbitals Done! real 6m56.994s user 5m17.282s sys 4m56.695s
This computation produced the same image with the correct orientation. I used a Bitmap class I created to use QuartzCore instead of the TARGA code from the C version. Eventually I produced this image.
By the way, I recommend you download one of the two images to examine the detail. What you are seeing is the cumulative result of each point in the set as it is iterated. The values are mapped back to a bitmap for viewing.
I added the orbitals functionality to the same program that computed the above traditional view of the Mandelbrot Set. It uses vDSP and Grand Central Dispatch. Unfortunately, Something rather bad happens.
Triton:Desktop david$ time ./OrbitalsSwift Killed: 9 real 6m16.576s user 29m27.176s sys 7m16.144s
No image is produced. The code does work for smaller images with fewer iterations. Running in the debugger is extremely time intensive. So I don’t know why it is getting killed. The debugger run looks like this.
The major take away on this is that Swift is not C or C++. For high performance computing, code has to be structured differently. Algorithmic analysis and profiling are critical, particularly when memory usage can become excessive. The C implementation has the advantage of running in constant space in spite of being a single threaded process. Using Grand Central Dispatch for threading is very easy. But it is no substitute for a bad algorithm.
You may download and play with the code used for these images from here. The code isn’t cleaned up and is certainly not production ready. There is also a dearth of comments. Sorry about that. I also assume the reader of the code is familiar with calculating the Mandelbrot Set.