So I've been working on the Darwin hobby project again recently and decided to find out where the program is spending all of it's time. It turns out that there are some really nice profiling tools in Haskell (GHC to be specific). Armed with that, I found out rather quickly that the bottleneck was the getPixel function I added to the GD bindings.
My first thought was that it would be nice to grab all of the pixels at once instead of repeated (slow) calls to getPixel. So I read up on Haskell FFI and the GD documentation and churned out the following:
This code returns a nice Haskell array of arrays with the color information. This improved the speed from 1 minute per 10 iterations to 1 second per 10 iterations -- about a 60x improvement!
However, this only works with true color images at this point; no indexed palette support since that information gets stored elsewhere in the GD image struct. All in all, it was a very pleasant and rewarding experience into Haskell. Next on the list is (Erlang-style maybe?) parallelization.
BTW, the GD binding code is under the dependencies folder here.