मैं एक ही पंक्ति में समान कार्यों को एक साथ करने की आदत में हूं। उदाहरण के लिए, अगर मैं पर फिल्टर करने के लिए की जरूरत है a, bऔर cएक डेटा तालिका में, मैं उन्हें एक साथ एक में डाल देता हूँ []ands के साथ। कल, मैंने देखा कि मेरे विशेष मामले में इसके बजाय अविश्वसनीय रूप से धीमा और परीक्षण किया गया था। मैंने नीचे एक उदाहरण शामिल किया है।
सबसे पहले, मैं यादृच्छिक संख्या जनरेटर को बीजता हूं , 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))
अगला, मैं अपने तरीकों को परिभाषित करता हूं। पहला अप्रोच चेन एक साथ फिल्टर करता है। दूसरा ANDs फ़िल्टर को एक साथ करता है।
# 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
2019-10-25 को रेप्रेक्स पैकेज (v0.3.0) द्वारा बनाया गया
इस मामले में, जंजीरों को चलाने का समय लगभग 70% कम हो जाता है। यह एक केस क्यों है? मेरा मतलब है, डेटा तालिका में हुड के तहत क्या हो रहा है? मैंने उपयोग करने के खिलाफ कोई चेतावनी नहीं देखी है &, इसलिए मुझे आश्चर्य हुआ कि अंतर इतना बड़ा है। दोनों ही मामलों में वे समान स्थितियों का मूल्यांकन करते हैं, ताकि अंतर न हो। AND मामले में, &एक त्वरित ऑपरेटर है और फिर इसे केवल एक बार डेटा तालिका को फ़िल्टर करना होता है (यानी, ANDs से उत्पन्न तार्किक वेक्टर का उपयोग करते हुए), जैसा कि चेनिंग मामले में तीन बार फ़िल्टर करने का विरोध किया गया है।
बोनस का सवाल
क्या यह सिद्धांत सामान्य रूप से डेटा टेबल संचालन के लिए है? क्या मॉड्यूलर काम करना हमेशा बेहतर रणनीति होती है?
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इन कटऑफ के लिए उपयोग किया है )।