Looks like divMod' function in Data.Fixed takes order of ~200ns (criterion benchmark on x86 Mac) per operation in my testing. What I did was to disable divMod' in a function I wrote, then compare benchmarking times before and after to come up with net overhead. With divMod' enabled, the function took ~230ns, and ~30ns with it disabled.
Is there a faster alternative to divMod' I could use? I could also specialize it to a single type, like Double to help speed it up.
Looked around but didn't see any mention about 'divMod'` performance. So, asking here.
I can't use quotRem directly because I need to do division on a double.
CodePudding user response:
It looks like the library function is defined in this way:
-- | Generalisation of 'div' to any instance of 'Real'
div' :: (Real a,Integral b) => a -> a -> b
div' n d = floor ((toRational n) / (toRational d))
-- | Generalisation of 'divMod' to any instance of 'Real'
divMod' :: (Real a,Integral b) => a -> a -> (b,a)
divMod' n d = (f,n - (fromIntegral f) * d) where
f = div' n d
You could adapt that to Double and simplify it, at the cost of some approximation:
divDouble :: Double -> Double -> Int
divDouble n d = floor (n / d)
{-#INLINABLE divDouble #-}
divDoubleMod :: Double -> Double -> (Int,Double)
divDoubleMod n d = (f,n - (fromIntegral f) * d) where
f = divDouble n d
{-#INLINABLE divDoubleMod #-}
Hopefully, Double division is faster than the original division on Rational, even if it's more approximated.
