[Haskell-beginners] Cheap lookup tables

Paul Sargent psarge at gmail.com
Tue Dec 14 18:13:27 CET 2010


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


More information about the Beginners mailing list