On Tuesday 29 January 2013, 03:27:41, Artyom Kazak 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?
It's not necessarily performed twice. func a b = case a `quotRem` b of (q, r) -> q+r produces idivq 8(%rbp) movq %rax,%rbx movq $GHC.Int.I32#_con_info,-8(%r12) movslq %edx,%rax movslq %ebx,%rbx addq %rax,%rbx as the relevant part of the assembly, with only one idivq instruction. I don't know whether you can rely on the code generator emitting only one division instruction in all cases, but in simple cases, it does (on x86_64, at least). Cheers, Daniel _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe