Предположим, что у нас есть vector
(или data.frame
):
set.seed(1)
x <- sample(10, 1e6, TRUE)
И каждый хочет получить все значения x
, где x > 4
, скажем:
a1 <- x[x > 4] # (or)
a2 <- x[which(x > 4)]
identical(a1, a2) # TRUE
Я думаю, что большинство людей предпочитают x[x > 4]
. Но удивительно (по крайней мере для меня), подмножество с использованием which
выполняется быстрее!
require(microbenchmark)
microbenchmark(x[x > 4], x[which(x > 4)], times = 100)
Unit: milliseconds
expr min lq median uq max neval
x[x > 4] 56.59467 57.70877 58.54111 59.94623 104.51472 100
x[which(x > 4)] 26.62217 27.64490 28.31413 29.97908 99.68973 100
Это примерно в 2,1 раза быстрее на моем.
Одна из возможностей разницы, я думал, может быть связана с тем, что which
не рассматривает NA
, но >
возвращает их также. Но тогда логическая операция сама по себе должна быть причиной этой разницы, что не так (очевидно). То есть:
microbenchmark(x > 4, which(x > 4), times = 100)
Unit: milliseconds
expr min lq median uq max neval
x > 4 8.182576 10.06163 12.68847 14.64203 60.83536 100
which(x > 4) 18.579746 19.94923 21.43004 23.75860 64.20152 100
Использование which
примерно в 1.7 раза медленнее перед подмножеством. Но which
, похоже, сильно подтягивается во время подмножества.
Кажется невозможным использовать мое обычное оружие выбора debugonce
(благодаря @GavinSimpson) в качестве which
вызывает .Internal(which(x))
, тогда как ==
вызывает .Primitive("==")
.
Поэтому мой вопрос: почему [
на numeric
тип, полученный из which
быстрее, чем логический вектор, полученный из >
? Любые идеи?