반응형
ifelse는 실제로 매번 두 벡터를 모두 계산합니까? 느린가요?
ifelse
실제로 각 벡터의 전체와 같이 yes
및 no
벡터를 모두 계산 합니까 ? 아니면 각 벡터에서 일부 값을 계산합니까?
또한 ifelse
정말 느린가요?
예. (예외 있음)
ifelse
그 yes
가치와 가치를 모두 계산합니다 no
. test
조건이 all TRUE
또는 all 인 경우를 제외하고 FALSE
.
난수를 생성하고 실제로 생성 된 수를 관찰하여이를 확인할 수 있습니다. (을 되돌려 서 seed
).
# TEST CONDITION, ALL TRUE
set.seed(1)
dump <- ifelse(rep(TRUE, 200), rnorm(200), rnorm(200))
next.random.number.after.all.true <- rnorm(1)
# TEST CONDITION, ALL FALSE
set.seed(1)
dump <- ifelse(rep(FALSE, 200), rnorm(200), rnorm(200))
next.random.number.after.all.false <- rnorm(1)
# TEST CONDITION, MIXED
set.seed(1)
dump <- ifelse(c(FALSE, rep(TRUE, 199)), rnorm(200), rnorm(200))
next.random.number.after.some.TRUE.some.FALSE <- rnorm(1)
# RESET THE SEED, GENERATE SEVERAL RANDOM NUMBERS TO SEARCH FOR A MATCH
set.seed(1)
r.1000 <- rnorm(1000)
cat("Quantity of random numbers generated during the `ifelse` statement when:",
"\n\tAll True ", which(r.1000 == next.random.number.after.all.true) - 1,
"\n\tAll False ", which(r.1000 == next.random.number.after.all.false) - 1,
"\n\tMixed T/F ", which(r.1000 == next.random.number.after.some.TRUE.some.FALSE) - 1
)
다음 출력을 제공합니다.
Quantity of random numbers generated during the `ifelse` statement when:
All True 200
All False 200
Mixed T/F 400 <~~ Notice TWICE AS MANY numbers were
generated when `test` had both
T & F values present
소스 코드 자체에서도 볼 수 있습니다.
.
.
if (any(test[!nas]))
ans[test & !nas] <- rep(yes, length.out = length(ans))[test & # <~~~~ This line and the one below
!nas]
if (any(!test[!nas]))
ans[!test & !nas] <- rep(no, length.out = length(ans))[!test & # <~~~~ ... are the cluprits
!nas]
.
.
Notice that yes
and no
are computed only if there is some non-NA
value of test
that is TRUE
or FALSE
(respectively).
At which point -- and this is the imporant part when it comes to efficiency -- the entirety of each vector is computed.
Ok, but is it slower?
Lets see if we can test it:
library(microbenchmark)
# Create some sample data
N <- 1e4
set.seed(1)
X <- sample(c(seq(100), rep(NA, 100)), N, TRUE)
Y <- ifelse(is.na(X), rnorm(X), NA) # Y has reverse NA/not-NA setup than X
These two statements generate the same results
yesifelse <- quote(sort(ifelse(is.na(X), Y+17, X-17 ) ))
noiflese <- quote(sort(c(Y[is.na(X)]+17, X[is.na(Y)]-17)))
identical(eval(yesifelse), eval(noiflese))
# [1] TRUE
but one is twice as fast as the other
microbenchmark(eval(yesifelse), eval(noiflese), times=50L)
N = 1,000
Unit: milliseconds
expr min lq median uq max neval
eval(yesifelse) 2.286621 2.348590 2.411776 2.537604 10.05973 50
eval(noiflese) 1.088669 1.093864 1.122075 1.149558 61.23110 50
N = 10,000
Unit: milliseconds
expr min lq median uq max neval
eval(yesifelse) 30.32039 36.19569 38.50461 40.84996 98.77294 50
eval(noiflese) 12.70274 13.58295 14.38579 20.03587 21.68665 50
반응형
'Nice programing' 카테고리의 다른 글
프로토 타입과 클로저가있는 객체 지향 자바 스크립트 (0) | 2020.11.28 |
---|---|
API 키 생성을위한 최상의 접근 방식 (0) | 2020.11.28 |
Rust에서 벡터를 정렬하는 방법? (0) | 2020.11.28 |
일부 웹 사이트의 제목에? utf8 = ✓가있는 이유는 무엇입니까? (0) | 2020.11.28 |
XPath-특정 유형의 자식이없는 노드 가져 오기 (0) | 2020.11.28 |