Home > OS >  divMod' alternative for faster calculations
divMod' alternative for faster calculations

Time:01-15

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.

  •  Tags:  
  • Related