
I've just done some profiling on my application, and I've found that about 50% of my time and allocations is taken by two functions. All these are a functions which return constants from tables. At the moment they look something like this (I'm using the dimensional package to handle SI Units, hence the *~ one): buehlmannGradient :: (Fractional a) => Gas -> Int -> Dimensionless a buehlmannGradient Nitrogen 1 = 1.7928 *~ one buehlmannGradient Nitrogen 2 = 1.5352 *~ one [...] buehlmannGradient Nitrogen 15 = 1.0414 *~ one buehlmannGradient Nitrogen 16 = 1.0359 *~ one buehlmannGradient Helium 1 = 2.0964 *~ one buehlmannGradient Helium 2 = 1.7400 *~ one [...] buehlmannGradient Helium 15 = 1.0850 *~ one buehlmannGradient Helium 16 = 1.0791 *~ one This one causes 36% of my time. The other is similar: buehlmannZeroPoint :: (Fractional a) => Gas -> Int -> Int -> Pressure a buehlmannZeroPoint Nitrogen 1 mode = ([29.6, 29.6, 29.6] *~~ msw) !! mode - buehlmannGradient Nitrogen 1 * (10 *~ msw) [...] Again, 16 Cases times two gases. This one uses 14.5%. They tend to be called in pairs, and the first function is called about 100,000 times. The second about 50,000 times (which then causes 50,000 of the first function). What's my best strategy for optimising these functions? Is it the pattern match that's hurting me? Can I write them in a better way, or do I need to look at how I'm using them? Obviously calling them less often would help, but I'm not sure what I'd do to my code to achieve this. These constants are used in lots of fairly diverse areas of my code, and they're encapsulated into functions to stop magic numbers flying around. Thanks Paul

On Tue, Dec 14, 2010 at 6:13 PM, Paul Sargent
I've just done some profiling on my application, and I've found that about 50% of my time and allocations is taken by two functions. All these are a functions which return constants from tables.
<snip>
They tend to be called in pairs, and the first function is called about 100,000 times. The second about 50,000 times (which then causes 50,000 of the first function).
What's my best strategy for optimising these functions?
Maybe looking it up in an array helps. You'd need an Ix instance for Gas, which is easy (I'm not sure whether Ix can be derived).
Is it the pattern match that's hurting me?
Hard to say, but with pattern matching, it may take a lot of sequential comparisons to find the value, which *may* cause it to use a lot of time.
Can I write them in a better way, or do I need to look at how I'm using them?
Obviously calling them less often would help, but I'm not sure what I'd do to my code to achieve this. These constants are used in lots of fairly diverse areas of my code, and they're encapsulated into functions to stop magic numbers flying around.
Thanks
Paul

Would specializing the functions to Double then using realToFrac only when necessary improve things? (It might make things worse of course...) buehlmannGradient :: Gas -> Int -> Double
participants (3)
-
Daniel Fischer
-
Paul Sargent
-
Stephen Tetley