On Mon, Jan 28, 2013 at 4:27 PM, Artyom Kazak <artyom.ka...@gmail.com> wrote: > Hi! > > I’ve always thought that `quotRem` is faster than `quot` + `rem`, since both > `quot` and `rem` are just "wrappers" that compute both the quotient and the > remainder and then just throw one out. However, today I looked into the > implementation of `quotRem` for `Int32` and found out that it’s not true: > > quotRem x@(I32# x#) y@(I32# y#) > | y == 0 = divZeroError > | x == minBound && y == (-1) = overflowError > | otherwise = (I32# (narrow32Int# (x# `quotInt#` > y#)), > I32# (narrow32Int# (x# `remInt#` > y#))) > > Why? The `DIV` instruction computes both, doesn’t it? And yet it’s being > performed twice here. Couldn’t one of the experts clarify this bit? >
That code is from base 4.5. Here's base 4.6: quotRem x@(I32# x#) y@(I32# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) | otherwise = case x# `quotRemInt#` y# of (# q, r #) -> (I32# (narrow32Int# q), I32# (narrow32Int# r)) So it looks like it was improved in GHC 7.6. In particular, by this commit: http://www.haskell.org/pipermail/cvs-libraries/2012-February/014880.html Shachaf _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe