jabbalaci/SpeedTests

Use divrem instead of mod + div in Julia code

DNF2 opened this issue · 5 comments

DNF2 commented

Replace separate calls to mod and div with a single call to divrem for a ~25% speedup of the Julia code:

function is_munchausen(number, cache)
    n = number
    total = 0

    while n > 0
        (n, digit) = divrem(n, 10)  # <== here, then remove call to div
        if digit > 0
            @inbounds total += cache[digit]
        end
        if total > number
            return false
        end
    end

    return total == number
end
DNF2 commented

And here's another small improvement; remove one branch in the loop:

get_cache() = (0, ntuple(i -> i^i, 9)...)  # add entry for zero

function is_munchausen(number, cache)
    n = number
    total = 0

    while n > 0
        (n, digit) = divrem(n, 10)
        @inbounds total += cache[digit+1]
        if total > number
            return false
        end
    end

    return total == number
end

Does it change anything in the execution time?

DNF2 commented

Yes, the first suggestion gives roughly a 25% speedup, while the second one gives a further 20%, approximately.

I'm timing this from the REPL, though, not sure what it does from the command line, though I don't see that it should make a significant difference in compilation time.

DNF2 commented

Actually, the speedup is coming from using rem instead of mod, not from using any shortcut based on calculating both at once. So if you just change digit = mod(n, 10) into digit = rem(n, 10), you should get a similar speedup.

But divrem looks cleaner, and is a much-used idiom in Julia.

Thanks, it was merged.