# 通用的距离函数
function Minkowski(
x::Array{T,1},
y::Array{T,1},
p::Int
) where T <: Number
return sum(abs.(x - y).^p)^(1/p)
end
# 欧式距离-1
Euclidean(x::Array{T,1}, y::Array{T,1}) where T <: Number = Minkowski(x, y, 2)
# 欧式距离-2
function Euclidean2(
x::Array{T,1},
y::Array{T,1}
) where T <: Number
return sqrt(sum(abs2.(x - y)))
end
测试代码
using BenchmarkTools
rng = 10^5
x = rand(-rng:rng, rng)
y = rand(-rng:rng, rng)
help?> mapreduce
search: mapreduce
mapreduce(f, op, itr; [init])
Apply function f to each element in itr, and then reduce the result using the binary function op. If provided, init must be a neutral element for op that will be returne
for empty collections. It is unspecified whether init is used for non-empty collections. In general, it will be necessary to provide init to work with empty collections.
mapreduce is functionally equivalent to calling reduce(op, map(f, itr); init=init), but will in general execute faster since no intermediate collection needs to be
created. See documentation for reduce and map.
划重点:
but will in general execute faster since no intermediate collection needs to be created.
试一下:
julia> using BenchmarkTools
julia> x = randn(10^5);
julia> y = randn(10^5);
julia> function f(x,y)
dist = 0
for i in 1:length(x)
dist += (x[i]-y[i])^2
end
dist = sqrt(dist)
return dist
end
julia> @btime f(x,y)
121.136 μs (1 allocation: 16 bytes)
448.6707620555013
julia> @btime sqrt(reduce(+, map((a, b) -> abs2(a-b), x, y)))
225.889 μs (6 allocations: 781.41 KiB)
448.6707620554991
julia> @btime sqrt(mapreduce(((a, b),) -> abs2(a-b), +, zip(x, y)))
105.932 μs (10 allocations: 208 bytes)
448.6707620555013