Re: [Haskell-cafe] Foreign function performance: monadic vs pure

From: Gregory Collins
On Mon, Apr 11, 2011 at 3:55 PM, Serguei Son
wrote: So if I must use a safe function returning IO a, there is no way to improve its performance? To give you a benchmark, calling gsl_ran_ugaussian a million times in pure C takes only a second or two on my system.
In the C version, are you also producing a linked list containing all of the values? Because that's what mapM does. Your test is mostly measuring the cost of allocating and filling ~3 million machine words on the heap. Try mapM_ instead.
I've done some rough tests of a few versions, and I believe Gregory's analysis is correct. These are for calculating a sum of sines of 1..10^7 with ghc-7.0.3. version execution time IO, safe - 4.08s Pure, safe - 3.07s IO, unsafe - 2.77s Pure, unsafe - 1.95s For the IO versions, I used the following: main = foldM (\ !acc n -> fmap (acc +) $ c_sin_io n) [1..10^7] >>= print (this can possibly be improved; it was the first thing I thought of) The most important factor (as often the case with Haskell) is to pay attention to the space properties of your algorithm. Instead of using mapM, which forces the spine of the list, it's much better to interleave the fold step with the other IO. Note that the "acc" parameter is strict, this is necessary to avoid building a thunk. John L.
participants (1)
-
John Lato