PHP函数isset的R版本

  • 本文关键字:版本 isset 函数 PHP
  • 更新时间 :
  • 英文 :


我经常发现PHP中的isset()非常有帮助。试图创建它的R版本,我想出了以下内容:

isset <- function(x){
  a <- try(x, silent = TRUE)
  return(!inherits(a, "try-error") && !is.null(a) && (length(a) != 1L || !is.na(a)))
}

它由3个检查组成:

  • 对象存在吗?
  • 如果是,是NULL ?
  • 如果不是,且不是NA是否为矢量?

如上所述,isset非常慢:

1)简单情况,根本不需要isset

> microbenchmark(isset(NULL), isset(NA))
Unit: microseconds
        expr    min     lq median     uq   max neval
 isset(NULL) 11.867 12.509 12.830 13.310 62.54   100
   isset(NA) 12.829 13.471 14.112 14.433 22.45   100
2)更有用,但仍然可以使用is.null()
> test_var <- list(a = 1)
> microbenchmark(isset(test_var$b))
Unit: microseconds
              expr    min    lq median     uq     max neval
 isset(test_var$b) 12.509 13.15 13.791 14.112 112.892   100

3)这里确实有帮助,但也变得非常慢

> rm(test_var)
> microbenchmark(isset(test_var), isset(test_var$b), try(test_var$b, silent = TRUE))
Unit: microseconds
                           expr     min       lq   median       uq      max neval
                isset(test_var) 736.038 764.1015 780.4575 815.5755 1223.844   100
              isset(test_var$b) 737.001 764.7425 786.0700 815.0940  986.837   100
 try(test_var$b, silent = TRUE) 732.832 760.2525 779.3345 815.4155 1034.944   100

几乎所有的时间都花在了try上。

Q:考虑到在上述3种情况下它都需要返回FALSE,您如何重写isset以使其至少快两倍?

使用内置的exists:

isset <- function(x) {
  is_variable <- make.names(name <- deparse(substitute(x))) == name
  if (is_variable && !exists(name)) return(FALSE)
  !is.null(x) && (length(x) != 1L || !is.na(x))
}
# > microbenchmark(isset(test_var), isset(test_var$b))
# Unit: microseconds
#              expr    min      lq median      uq     max neval
# isset(test_var)   28.011 28.9115 29.278 29.6445  41.960   100
# isset(test_var$b) 47.656 49.1515 49.690 50.4170 137.049   100

最新更新