 # Is there any advantage with Int.quotientAndRemainder(dividingBy:) vs. using `/` and `%`?

I assume `.quotientAndRemainder(dividingBy:)` calculate both quotient and remainder values with fewer instructions then doing it separately with `/` and `%`?

For my use case, the code look a little less clear with `.quotientAndRemainder(dividingBy:)`:

``````extension Int {
// collect digits in reverse order, ignoring negative sign
var digitsInReverse: [Int] {
if self == 0 {
return 
}
var result = [Int]()
var n = abs(self)
while (n > 0) {
let (q, r) = n.quotientAndRemainder(dividingBy: 10) // is there anyway to assign quotient to `n` directly here?
result.append(r)
n = q
}
return result
}
}
``````

vs.

``````extension Int {
// collect digits in reverse order, ignoring negative sign
var digitsInReverse: [Int] {
if self == 0 {
return 
}
var result = [Int]()
var n = abs(self)
while (n > 0) {
result.append(n % 10)
n = n / 10
}
return result
}
}
``````

For "normal" types like `Int`, no, the two are equivalent, because the optimizer knows that division and remainder forma a pair. For integer types implemented in a library, there could be a difference.

(It's worth noting that neither of these will actually result in a divide instruction, because the compiler also knows that instead of dividing by 10 you can do a fixed-point multiplication by 1/10 and fixup rounding for negative inputs.)

4 Likes

If you use `sequence` and need to copy the variable you're mutating, into a constant, then `quotientAndRemainder` gets around the problem of already having something named `quotient`. But defer saves a line of code. I have no preference between the two if the performance is in fact identical.

``````public extension UnsignedInteger {
/// The digits that make up this number.
/// - Parameter radix: The base the result will use.
func digits(radix: Self = 10) -> [Self] {
sequence(state: self) { quotient in
guard quotient > 0
else { return nil }

defer { quotient /= radix }
}
.reversed()
}
}
``````
``````public extension UnsignedInteger {
/// The digits that make up this number.
/// - Parameter radix: The base the result will use.
func digits(radix: Self = 10) -> [Self] {
sequence(state: self) { quotient in
guard quotient > 0
else { return nil }

quotient = division.quotient
return division.remainder
}
.reversed()
}
}
``````

Worth noting that if one cares about performance (which is presumably why one is fussing with this at all), all of these digit-serial implementations are somewhat problematic, because there's a loop-carried dependency on the division that prevents an out-of-order CPU from extracting much/any ILP. What you would really like to do is split the input into groups of a few digits using division by 100, 1000, or 10000, and then extract individual digits from those (if you use groups of two or even three digits, a table lookup instead of division/remainder is pretty attractive).

You can also use a binary-tree approach for maximum ILP, but that only really matters if you have a distribution of inputs that's somewhat uniform, which is unusual.

4 Likes

Is this optimization only when the divisor 10 is a compile time constant? There is no such optimization if the divisor is a variable as @Jessy does with `radix`?

I actually want the digits in reverse order, but I have question, please see comment in code:

``````extension UnsignedInteger {
func digitsR(radix: Self = 10) -> UnfoldSequence<Self, Self> {    // Q: since UnfoldSequence conform to Sequence
//    func digitsR<S>(radix: Self = 10) -> S where S: Sequence, S.Element == Self {    // How to return Sequence instead?
sequence(state: self) { (quotient) -> Self? in
guard quotient > 0
else { return nil }

defer { quotient /= radix }