Optimise

Issue #3 resolved
Colin Gillespie created an issue

If the function is in a loop, the assert statements can have a massive impact on speed. In the example below, it is 100 times slower. Compare;

library(assertive)
geomean4 <- function(x, na.rm = FALSE)
{
  assert_is_numeric(x)
  if(any(is_negative(x), na.rm = TRUE))
  {
    warning("x contains negative values, so the
geometric mean makes no sense.")
    return(NaN)
  }
  na.rm <- coerce_to(use_first(na.rm), "logical")
  exp(mean(log(x), na.rm = na.rm))
}

f =  function(x, na.rm = FALSE) exp(mean(log(x), na.rm = na.rm))

x = rlnorm(100)
system.time(replicate(1e5, f(x)))
# Note only using 1e3
system.time(replicate(1e3, geomean4(x)))

Comments (3)

  1. Richard Cotton repo owner

    I just found another package for doing assertions called checkmate that has a lot of C code, so borrowing their code might be possible to speed things up.

  2. Richard Cotton repo owner

    The latest version of assertive allows you to turn off assertions (either individually, passing severity = "none", or globally, setting options(assertive.severity = "none")). The printing of assertion failure took some time; that logic is outsourced to a separate print method, so the processing is only done when failures occur.

    I think the geomean motivating example is a worst case, since that function is very fast. Usually, the processing time for actual function content, when you don't get a failure, should be large relative to the assertions. And if you do get a failure, fixing that is more important than the run-time.

    The C code in checkmate looks to mostly be reproducing base-R code for checking things like variable types. So I might be able to save a few milliseconds here and there by reducing the number of function calls, but I don't think it's worth my time to spend any more effort on this right now.

  3. Log in to comment