The big error you made originally is calling collect in every iteration of 
the loop. Just deleting collect speeds things up by 100x. The lesson is 
that you should (almost) never use collect.

The other lesson is: don't do [1:0.1:10]. It makes your code slower, and 
very soon your it will stop working correctly. Just delete [].

function mindist0(x, val)
    # your original
    min_i = 0
    min_x = 1.0
    for i=1:length(x)
        e = abs(collect(x)[i] - val)
        if e < min_x
            min_x = e
            min_i = i
        end
    end
    return (min_i, min_x)
end


function mindist1(x, val)
    #  same as the original, except removing 'collect'
    min_i = 0
    min_x = 1.0
    for i = 1:length(x)
        e = abs(x[i] - val)
        if e < min_x
            min_x = e
            min_i = i
        end
    end
    return (min_i, min_x)
end


function mindist2(x, val)
    # using enumerate to avoid indexing
    min_i = 0
    min_x = Inf
    for (i, xi) in enumerate(x)
        dist = abs(xi - val)
        if dist < min_x
            min_x = dist
            min_i = i
        end
    end
    return (min_i, min_x)
end


function test_dist(x, val, N)
    # putting time testing inside a function for optimal result
    @assert mindist0(x, val) == mindist1(x, val) == mindist2(x, val)
    @time for _ in 1:N mindist0(x, val) end
    @time for _ in 1:N mindist1(x, val) end
    @time for _ in 1:N mindist2(x, val) end
end


>> test_dist(1:0.1:10, 8.22, 1)
0.000060 seconds (182 allocations: 76.781 KB)
0.000001 seconds
0.000001 seconds

>> test_dist(1:0.1:10, 8.22, 1)
0.641741 seconds (1.82 M allocations: 749.817 MB, 7.57% gc time)
0.007380 seconds
0.005570 seconds

Reply via email to