यहाँ अनुभवहीन तरीका है,
all0 <- function(x, FUN)
all(vapply(x, FUN, logical(1)))
और एक अनुसंधान पाश ...
all1 <- function(x, FUN) {
for (xi in x)
if (!FUN(xi))
return(FALSE)
TRUE
}
...जो
library(compiler)
all1c <- cmpfun(all1)
संकलित किया जा सकता है ... या सी में लिखे
library(inline)
allc <- cfunction(signature(x="list", fun="function"), "
SEXP call = PROTECT(lang2(fun, R_NilValue));
int len = Rf_length(x);
for (int i = 0; i < len; ++i) {
SETCADR(call, VECTOR_ELT(x, i));
if (!LOGICAL(eval(call, R_GlobalEnv))[0]) {
UNPROTECT(1);
return Rf_ScalarLogical(FALSE);
}
}
UNPROTECT(1);
return Rf_ScalarLogical(TRUE);")
हम प्रदर्शन को मापने की जरूरत है, तो
library(microbenchmark)
सबसे ज्यादा मामले शर्त यह है कि होने लगते हैं पास
n <- 100000
x0 <- x <- vector("list", n)
microbenchmark(all0(x, is.null), all1(x, is.null), all1c(x, is.null),
allc(x, is.null))
## Unit: milliseconds
## expr min lq median uq max neval
## all0(x, is.null) 47.48038 50.58960 52.34946 54.10116 61.94736 100
## all1(x, is.null) 41.52370 44.40024 45.25135 46.68218 53.22317 100
## all1c(x, is.null) 33.76666 35.03008 35.71738 36.41944 45.37174 100
## allc(x, is.null) 13.95340 14.43153 14.78244 15.94688 19.41072 100
इसलिए हम संकलित आर संस्करण की तुलना में सी में तेजी से केवल 2x हैं - प्रत्येक परीक्षण पर एक फ़ंक्शन कॉल है, इसलिए हम केवल लूपिंग प्रति से बचत कर रहे हैं। सी पाश - सबसे अच्छा मामला है जब हम बाहर निकलने के तुरंत और स्पष्ट रूप से पाश का लाभ दिखा, लेकिन फिर न संकलन है और न ही सी कोड हमें
x[[1]] <- FALSE
microbenchmark(all0(x, is.null), all1(x, is.null), all1c(x, is.null),
allc(x, is.null))
## Unit: microseconds
## expr min lq median uq max neval
## all0(x, is.null) 45376.760 45772.5020 46108.5795 46655.005 54242.687 100
## all1(x, is.null) 1.566 1.9550 2.6335 12.015 14.177 100
## all1c(x, is.null) 1.367 1.7340 2.0345 9.359 17.438 100
## allc(x, is.null) 1.229 1.6925 4.6955 11.628 23.378 100
में मदद करता है यहाँ एक मध्यवर्ती मामला है, जो वास्तव में किसी भी आश्चर्य शामिल नहीं करता है संकलित आर लूप की तुलना में लगभग 2x तेज है, इसलिए लगभग 2x जल्दी हो जाता है।
x <- x0
x[[length(x)/2]] <- FALSE
microbenchmark(all0(x, is.null), all1(x, is.null), all1c(x, is.null),
allc(x, is.null))
## Unit: milliseconds
## expr min lq median uq max neval
## all0(x, is.null) 46.85690 49.92969 51.045519 52.653137 59.445611 100
## all1(x, is.null) 20.90066 21.92357 22.582636 23.077863 25.974395 100
## all1c(x, is.null) 16.51897 17.44539 17.825551 18.119202 20.535709 100
## allc(x, is.null) 6.98468 7.18392 7.312575 8.290859 9.460558 100
स्पष्ट रूप से सी स्तर (VECTOR_ELT(x, i) == R_NilValue
) पर शून्य के लिए परीक्षण, बहुत तेजी से है, इसलिए सी कोड है कि शून्य करने के लिए मूल्य की तुलना इसी आर कोड की तुलना में तेजी 100x के बारे में है। ऐसा लगता है कि सभी एनएलएल एक मूल्यवान हो सकता है, जबकि गति सामान्यता थी, लेकिन सामान्य उद्देश्य सी-लेवल के मामले में सभी इतने आकर्षक लगते नहीं हैं। और निश्चित रूप से सी कोड एनए या त्रुटि शर्तों से निपटता नहीं है।
आप सी ++ या RCpp :) – bartektartanus
में लिख सकते आप प्रत्येक व्यक्ति के लिए समस्या मतलब है, या सामान्य 'में all_fast' समारोह को लागू करने के' एक तरह से होगा Rcpp'? – Jeroen
नहीं ... आप आरसीपीपी फ़ंक्शन के लिए तर्क के रूप में फ़ंक्शन पास कर सकते हैं। – bartektartanus