绩效评估
其他答案忽略了一个重要方面 - 绩效。因此,让我简要回顾一下。为了使这个更加现实,我创建了两个包含100,000个元素的Integer
向量。
using StatsBase
a = sample(1:1_000_000, 100_000)
b = sample(1:1_000_000, 100_000)
为了知道一个良好的性能表现是什么,我在
R
中做了同样的事情,导致中位数性能为
4.4 毫秒
:
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)
Slower than
R
, but not by much. The syntax, however, could really use some improvement.
低效的解决方案
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)
比起 R
几乎慢了 800 倍(几乎比 R
慢了 1000 倍),这真的不值得一提。在我看来,这三个解决方案的语法也不是很好,但至少第一个解决方案看起来比“高性能解决方案”更好。
非解决方案
这个是这样的
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