I need to use an IF…ELSEIF…ELSE statement in a large loop and I therefore did the following test to find the fastest implementation. In the following code a random number between 0 and 5 is chosen. Based on this outcome, the outcome is multiplied by 10. I know this is a silly procedure, but it is purely meant for test purposes. The 0 has the largest occurrence, the 5 the smallest. In the code I implement 3 ways to do so: by a dictionary, by an IF statement that starts testing for the 0 and ends with 5 and an IF statement that starts testing for the 5 and ends with the 0. My idea is that, since the 0 is created most often, the first IF statement would be faster than the second. The code looks like this:
function test() d = Dict(0 => 0, 1 => 10, 2 => 20, 3 => 30, 4 => 40, 5 => 50) a = Float64 for i = 1:30000 a = Float64 for j = 1:10000 g = rand(Float64)*6 g *= g^2/36 g = trunc(Int64,g) #Option 1 g = d[g] #Option 2 if g == 0 g = 0 elseif g == 1 g = 10 elseif g == 2 g = 20 elseif g == 3 g = 30 elseif g == 4 g = 40 else g = 50 end #Option 3 if g == 5 g = 50 elseif g == 4 g = 40 elseif g == 3 g = 30 elseif g == 2 g = 20 elseif g == 1 g = 10 else g = 0 end push!(a,g) end end return a end a = test()
The push! statement is there since Julia needs to do something with the created numbers. Otherwise, Julia will just skip everything since nothing is done with those number.
For each test I comment two options so that I only use one option. The outcomes are as follows:
Without the three options (as a “zero” measurement")
julia> @time test() 6.045474 seconds (420.01 k allocations: 7.343 GiB, 10.85% gc time)
With option 1 (dictionary)
julia> @time test() 9.202082 seconds (420.01 k allocations: 7.343 GiB, 7.29% gc time)
With option 2 (IF with incremental numbers)
julia> @time test() 10.113319 seconds (420.01 k allocations: 7.343 GiB, 7.89% gc time)
This shows that using a dictionary is faster that using IF statements. Now the test with option 3 (IF with decremental numbers, starting with 5):
julia> @time test() 9.147968 seconds (420.01 k allocations: 7.343 GiB, 6.56% gc time)
Shorter?!! This is counter intuitive for me because the ‘0’ occurs much more often and, therefore, you would expect that starting checking for zeros in the IF statement would be faster that starting with ‘5’. But the opposite is true!
I have two questions:
- Why is this?
- What would be the best option if, based on the random number, a specific function needs to be called? I guess you cannot make a dictionary of functions …
Thanks a lot for your help.
PS: I performed the
@time at least two times before I marked the outcome.