# Question about Ref and about unique

**URL:** https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202
**Category:** New to Julia
**Tags:** question
**Created:** [October 22, 2021, 10:01am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202 "2021-10-22T10:01:47Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)
#### Post date: [October 22, 2021, 10:01am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/1 "2021-10-22T10:01:47Z")

</div>

Please see the below code:

```julia
x = rand(10_000_000);
@time unique(x);
# 1.6 seconds
@time unique(Ref(x))[1];
# 0.006373 seconds
unique(x) == unique(Ref(x))[1]
# true

```

Why would anyone use `unique` on it owns instead of unique + Ref ?  
Can’t Julia optimise this automatically?

Thank you

---

<div class="post-metadata">

### Author: ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)
#### Post date: [October 22, 2021, 10:11am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/2 "2021-10-22T10:11:54Z")

</div>

They are not the same:

```julia
x = [2, 3, 2, 3]
unique(x) # [2, 3]
unique(Ref(x))[1] # [2, 3, 2, 3]
unique(Ref(x))[1] === x # true

```

Note that `unique(Ref(x))[1]` just returns `x`, since `Ref(x)` is equivalent here to a vector with a single element `x`.

---

<div class="post-metadata">

### Author: ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)
#### Post date: [October 22, 2021, 10:12am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/3 "2021-10-22T10:12:59Z")

</div>

```julia
julia> x = rand(1:10, 10);

julia> x
10-element Vector{Int64}:
  3
  6
  1
  8
  7
  7
 10
  6
  1
  3

julia> unique(x)
6-element Vector{Int64}:
  3
  6
  1
  8
  7
 10

julia> unique(Ref(x))
1-element Vector{Vector{Int64}}:
 [3, 6, 1, 8, 7, 7, 10, 6, 1, 3]

```

Note that `unique(Ref(x))` doesn’t do what you think it does. `Ref(x)` effectively makes `x` “look like a scalar” for `unique` which is why it just returns `x` itself - the only unique element - in a vector. And, of course, that’s much cheaper / faster than actually finding the unique values.

---

<div class="post-metadata">

### Author: ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)
#### Post date: [October 22, 2021, 10:21am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/4 "2021-10-22T10:21:11Z")

</div>

Thank you.  
Unique in Julia seems to be very slow compare to unique in R for the example I provided … not sure to understand why…

```nohighlight
x = runif(1e7)
system.time(unique(x))
# 0.85 sec

```

---

<div class="post-metadata">

### Author: ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)
#### Post date: [October 22, 2021, 10:50am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/6 "2021-10-22T10:50:24Z")

</div>

If you don’t care about the order of the returned elements, you can try something like the following, which seems to reduce the timings by a factor ~2:

```julia
x = rand(10_000_000);

# Assumes `xs` is already sorted.
function unique_sorted(xs)
    xprev = first(xs)
    ys = [xprev]
    for x ∈ xs
        if x != xprev
            push!(ys, x)
        end
        xprev = x
    end
    ys
end

function unique_sort(xs)
    ys = sort(xs)
    unique_sorted(ys)
end

julia> using BenchmarkTools

julia> @benchmark unique($x)
BenchmarkTools.Trial: 3 samples with 1 evaluation.
 Range (min … max): 1.813 s … 2.103 s ┊ GC (min … max): 4.31% … 5.35%
 Time (median): 2.045 s ┊ GC (median): 3.82%
 Time (mean ± σ): 1.987 s ± 153.230 ms ┊ GC (mean ± σ): 3.32% ± 2.64%

  █ █ █  
  █▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁█ ▁
  1.81 s Histogram: frequency by time 2.1 s <

 Memory estimate: 323.67 MiB, allocs estimate: 80.

julia> @benchmark unique_sort($x)
BenchmarkTools.Trial: 6 samples with 1 evaluation.
 Range (min … max): 878.788 ms … 986.507 ms ┊ GC (min … max): 0.43% … 8.84%
 Time (median): 893.003 ms ┊ GC (median): 0.04%
 Time (mean ± σ): 905.269 ms ± 40.648 ms ┊ GC (mean ± σ): 1.69% ± 3.57%

  ██ █ ██ █  
  ██▁▁▁▁█▁▁▁██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
  879 ms Histogram: frequency by time 987 ms <

 Memory estimate: 223.13 MiB, allocs estimate: 20.

```

---

<div class="post-metadata">

### Author: ![gitboy16](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gitboy16/32/24906_2.png) [@gitboy16](https://discourse.julialang.org/u/gitboy16)
#### Post date: [October 22, 2021, 10:58am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/7 "2021-10-22T10:58:40Z")

</div>

Thank you @jipolanco , this is helpful and improve performance but it is still slower than R. I think I can write something in C which is faster than the R version. I will also try to write it in Julia to see how it compares. Thanks again.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 22, 2021, 11:00am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/8 "2021-10-22T11:00:37Z")

</div>

Please share it! It would be nice to see what algorithm R is using.

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [October 22, 2021, 11:52am UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/9 "2021-10-22T11:52:37Z")

</div>

Instead of `unique(x)`, another way of writing unique sorted:

```julia
function uniquesorted(x)
   y = sort(x)
   y[diff([y; Inf]) .!= 0]
end

x = rand(10_000_000);
using BenchmarkTools
@btime unique($x) # 1.254 s (80 allocations: 360 MiB)
@btime uniquesorted($x) # 932 ms (12 allocations: 306 MiB)

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [October 22, 2021, 4:40pm UTC](https://discourse.julialang.org/t/question-about-ref-and-about-unique/70202/10 "2021-10-22T16:40:31Z")

</div>

**As a side note:** with 64-bit floats and `x = rand(10_000_000)`, the probabability that `unique(x) != x` should be extremelly low, no?
