Rewritten from scratch
https://cran.r-project.org/web/packages/data.table/vignettes/datatable-keys-fast-subset.html. Section 4) binary search vs vector scans states that, for example, the following
flights[origin == "JFK" & dest == "MIA"]
will get , I quote, automatically optimized to use binary search.
However!, I've taken the liberty to modify their included example and compare selection with negation, as you're trying to, and the results weren't so good :/
N = 2e7L
DT = data.table(x = sample(letters, N, TRUE),
y = sample(1000L, N, TRUE),
z = sample(c(T, F), N, TRUE, probs=c(0.00001, 0.99999)),
val = runif(N))
key(DT) # should be null
t1 <- system.time(ans1 <- DT[z == T & x == "g"])
t2 <- system.time(ans1 <- DT[z != F & x == "g"])
setkey(DT, x, z)
t3 <- system.time(ans1 <- DT[z == T & x == "g"])
t4 <- system.time(ans1 <- DT[z != F & x == "g"])
on my machine the results go as follows:
> t1
user system elapsed
0.464 0.001 0.124
> t2
user system elapsed
0.169 0.000 0.169
> t3
user system elapsed
0.002 0.000 0.002
> t4
user system elapsed
0.168 0.000 0.167
It seems that if there's negation in the selections, not only do we not use the fast binary search, we also only utilise only one core (compare t1 and t2 - user and elapsed times). In this scenario, we only get the insane binary performance if the selects don't use negation and the keys are set. This is disappointing, and maybe even a bug?