비슷한 작업을 한 줄에 모으는 습관이 있습니다. 내가 필터링해야하는 경우 예를 들어 a
, b
및 c
데이터 테이블에, 나는 하나에 함께 넣어 것이다 []
AND 연산과 함께. 어제, 나는 내 특별한 경우에 이것이 매우 느리고 체인 필터를 테스트 한 것으로 나타났습니다. 아래에 예제를 포함 시켰습니다.
먼저 난수 생성기를 시드하고 data.table을 로드 하고 더미 데이터 세트를 만듭니다.
# Set RNG seed
set.seed(-1)
# Load libraries
library(data.table)
# Create data table
dt <- data.table(a = sample(1:1000, 1e7, replace = TRUE),
b = sample(1:1000, 1e7, replace = TRUE),
c = sample(1:1000, 1e7, replace = TRUE),
d = runif(1e7))
다음으로 메소드를 정의합니다. 첫 번째 접근 체인은 함께 필터링합니다. 두 번째는 필터를 함께 AND합니다.
# Chaining method
chain_filter <- function(){
dt[a %between% c(1, 10)
][b %between% c(100, 110)
][c %between% c(750, 760)]
}
# Anding method
and_filter <- function(){
dt[a %between% c(1, 10) & b %between% c(100, 110) & c %between% c(750, 760)]
}
여기서 나는 동일한 결과를 제공하는지 확인합니다.
# Check both give same result
identical(chain_filter(), and_filter())
#> [1] TRUE
마지막으로 벤치마킹했습니다.
# Benchmark
microbenchmark::microbenchmark(chain_filter(), and_filter())
#> Unit: milliseconds
#> expr min lq mean median uq max
#> chain_filter() 25.17734 31.24489 39.44092 37.53919 43.51588 78.12492
#> and_filter() 92.66411 112.06136 130.92834 127.64009 149.17320 206.61777
#> neval cld
#> 100 a
#> 100 b
reprex 패키지 (v0.3.0)로 2019-10-25에 작성
이 경우 체인을 사용하면 실행 시간이 약 70 % 단축됩니다. 왜 이런 경우입니까? 데이터 테이블에서 어떤 일이 벌어지고 있습니까? 사용에 대한 경고를 보지 못했기 &
때문에 차이가 너무 크다는 것에 놀랐습니다. 두 경우 모두 동일한 조건을 평가하므로 차이가 없어야합니다. AND의 경우, &
빠른 연산자이며 체인의 경우 세 번 필터링하는 것과 달리 데이터 테이블을 한 번만 필터링하면됩니다 (즉, AND에서 생성 된 논리 벡터 사용).
보너스 질문
이 원칙은 일반적으로 데이터 테이블 작업에 적용됩니까? 모듈화 작업이 항상 더 나은 전략입니까?
base
다음을 수행하여 벡터와 관찰 : chain_vec <- function() { x <- which(a < .001); x[which(b[x] > .999)] }
와 and_vec <- function() { which(a < .001 & b > .999) }
. (여기서 a
와 b
같은 길이의 벡터 runif
- n = 1e7
이 컷오프에 사용 했습니다).