绩效考核
其他答案忽略了一个重要方面 - 性能。所以,让我简要回顾一下。为了实现这一点,我创建了两个 Integer 向量,每个向量包含 100,000 个元素。
using StatsBase
a = sample(1:1_000_000, 100_000)
b = sample(1:1_000_000, 100_000)
为了知道什么是体面的表现,我在R做了同样的事情,导致4.4 ms的平均表现:
# R code
a <- sample.int(1000000, 100000)
b <- sample.int(1000000, 100000)
microbenchmark::microbenchmark(a %in% b)
Unit: milliseconds
expr min lq mean median uq max neval
a %in% b 4.09538 4.191653 5.517475 4.376034 5.765283 65.50126 100
高性能解决方案
findall(in(b),a)
5.039 ms (27 allocations: 3.63 MiB)
比R 慢,但也不是很多。然而,语法确实需要一些改进。
性能不佳的解决方案
a .∈ Ref(b)
in.(a,Ref(b))
findall(x -> x in b, a)
3.879468 seconds (6 allocations: 16.672 KiB)
3.866001 seconds (6 allocations: 16.672 KiB)
3.936978 seconds (178.88 k allocations: 5.788 MiB)
慢 800 倍(几乎比 R 慢 1000 倍)——这真的没什么好写的。在我看来,这三个的语法也不是很好,但至少第一个解决方案在我看来比“高性能解决方案”更好。
is-not-a 解决方案
这里是这个
indexin(a,b)
5.287 ms (38 allocations: 6.53 MiB)
是高性能的,但对我来说这不是一个解决方案。它包含nothing 元素,其中该元素不在另一个向量中。在我看来,主要应用是对向量进行子集化,这不适用于此解决方案。
a[indexin(b,a)]
ERROR: ArgumentError: unable to check bounds for indices of type Nothing