# Euclidean distance from one point

**URL:** <https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594>\
**Category:** Performance\
**Tags:** question\
**Created:** [June 17, 2020, 2:05pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594 "2020-06-17T14:05:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Geoffrey](https://avatars.discourse-cdn.com/v4/letter/g/bc8723/32.png) [@Geoffrey](https://discourse.julialang.org/u/Geoffrey)\
**Post date:** [June 17, 2020, 2:05pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/1 "2020-06-17T14:05:16Z")

</div>

Hi, I’m looking for a way to compute an array representing the radius of the polar or spherical coordinates given the array sizes and a center point. I have this code for now but it’s incredibly slow and I’m looking for ways to improve it and tips to understand why it is slow:

```julia
using BenchmarkTools
function euclideandst(sz, p)
    # sz = size of the Array
    # p coordinates of the center point
    N = length(sz) # number of dimension
    return [sqrt(sum(x -> x .* x, [i[j] - c[j] for j = 1:N])) for i = CartesianIndices(sz)]
end
sz = (1024, 1024, 25)
c = (sz .+ 1) ./ 2
@btime dst = euclideandst($sz, $c)
39.293 s (314624005 allocations: 8.40 GiB)

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [June 17, 2020, 2:21pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/2 "2020-06-17T14:21:06Z")

</div>

I would highly reccomend `Distances.jl` for doing this type of work. It is incredibly well optimized.

---

<div class="post-metadata">

**Author:** ![cstich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstich/32/18665_2.png) [@cstich](https://discourse.julialang.org/u/cstich)\
**Post date:** [June 17, 2020, 2:40pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/3 "2020-06-17T14:40:30Z")

</div>

Also if you use several threads, using unsafe views ([UnsafeArrays.jl](https://github.com/JuliaArrays/UnsafeArrays.jl)) can make quite a bit of difference as well (even if you use the `Distances.jl` package).

Something like this should work; taken from [ParalllelKMeans](https://github.com/PyDataBlog/ParallelKMeans.jl/blob/master/src/kmeans.jl).

```
"""
distance(metric, X1, X2, i1, i2)
Allocationless calculation of distance between vectors X1[:, i1] and X2[:, i2] defined by the supplied distance metric.
"""
@inline distance(metric, X1, X2, i1, i2) = evaluate(metric, uview(X1, :, i1), uview(X2, :, i2))

```

Edit: Update with link to UnsafeArrays

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [June 17, 2020, 2:41pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/4 "2020-06-17T14:41:20Z")

</div>

Do `uview`s help at all once 1.5 is out?

---

<div class="post-metadata">

**Author:** ![cstich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstich/32/18665_2.png) [@cstich](https://discourse.julialang.org/u/cstich)\
**Post date:** [June 17, 2020, 2:44pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/5 "2020-06-17T14:44:34Z")

</div>

I don’t know for sure but it looks like in most cases `uviews` should indeed by unnecessary with 1.5

[https://github.com/JuliaArrays/UnsafeArrays.jl/issues/8](https://github.com/JuliaArrays/UnsafeArrays.jl/issues/8)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 17, 2020, 3:08pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/6 "2020-06-17T15:08:03Z")

</div>

> [@Geoffrey](#):
>
> Hi, I’m looking for a way to compute an array representing the radius of the polar or spherical coordinates given the array sizes and a center point. I have this code for now but it’s incredibly slow and I’m looking for ways to improve it and tips to understand why it is slow:

First, realize that in your innermost loop you are allocating a little 3-component array on every iteration (every `i`) just to sum it, which is incredibly wasteful and inefficient. Second, you have a bug: although you are passing `c` as the parameter `p` in your function, your function actually refers to the global variable `c` rather than to the parameter `p`, and global variables are slow in Julia.

Simply fixing the bug (changing `c` to `p` in the function) speeds it up by a factor of 20 for me. Getting rid of the inner-loop allocations by changing the `sum` call to `sum(j -> (i[j] - p[j])^2, 1:N))` speeds it up by another factor of 6:

```julia
function euclideandst2(sz, p)
    # sz = size of the Array
    # p coordinates of the center point
    N = length(sz) # number of dimension
    return [sqrt(sum(j -> (i[j] - p[j])^2, 1:N)) for i = CartesianIndices(sz)]
end

```

I get another factor of 2 (down to 129ms) by exploiting the fact that the length `N` of the tuples is known at compile-time, so the loop can be unrolled by the compiler if we use some tricks:

```julia
function euclideandst3(sz::NTuple{N}, p::NTuple{N}) where {N}
    # sz = size of the Array
    # p coordinates of the center point
    return [sqrt(sum(ntuple(j -> (i[j] - p[j])^2, Val{N}()))) for i = CartesianIndices(sz)]
end

```

Automating this sort of trick, using a compile-time array length, is one of the reasons why [the StaticArrays package](https://github.com/JuliaArrays/StaticArrays.jl) is the method of choice for computations with small coordinate vectors.

Of course, you can get further speedups by multiple threads, etcetera, and if there is an optimized package that does what you need then by all means use it. But hopefully the `euclideandst2` function convinces you that you can obtain quite decent in performance in Julia just by [following a few simple guidelines](https://docs.julialang.org/en/v1/manual/performance-tips/index.html) without advanced wizardry.

---

<div class="post-metadata">

**Author:** ![Geoffrey](https://avatars.discourse-cdn.com/v4/letter/g/bc8723/32.png) [@Geoffrey](https://discourse.julialang.org/u/Geoffrey)\
**Post date:** [June 17, 2020, 3:59pm UTC](https://discourse.julialang.org/t/euclidean-distance-from-one-point/41594/7 "2020-06-17T15:59:45Z")

</div>

Thanks a lot for your time in providing me such a detailed answer ! I didn’t know about the `Distances.jl` package and as I’m in the learning phase of the julia language I think it’s good practice to try to implement such basic function. Thanks to you I also understand a bit more how julia works and how to get the maximum of it !
