# Performance benefit by using compiled model definitions in mkin

#### Johannes Ranke

#### 2018-02-06

## Model that can also be solved with Eigenvalues

This evaluation is taken from the example section of mkinfit. When using an mkin version equal to or greater than 0.9-36 and a C compiler (gcc) is available, you will see a message that the model is being compiled from autogenerated C code when defining a model using mkinmod. The `mkinmod()` function checks for presence of the gcc compiler using

    Sys.which("gcc")

    ##            gcc
    ## "/usr/bin/gcc"

First, we build a simple degradation model for a parent compound with one metabolite.

    library("mkin", quietly = TRUE)
    SFO_SFO <- mkinmod(
      parent = mkinsub("SFO", "m1"),
      m1 = mkinsub("SFO"))

    ## Successfully compiled differential equation model from auto-generated C code.

We can compare the performance of the Eigenvalue based solution against the compiled version and the R implementation of the differential equations using the benchmark package.

    if (require(rbenchmark)) {
      b.1 <- benchmark(
        "deSolve, not compiled" = mkinfit(SFO_SFO, FOCUS_2006_D,
                                          solution_type = "deSolve",
                                          use_compiled = FALSE, quiet = TRUE),
        "Eigenvalue based" = mkinfit(SFO_SFO, FOCUS_2006_D,
                                     solution_type = "eigen", quiet = TRUE),
        "deSolve, compiled" = mkinfit(SFO_SFO, FOCUS_2006_D,
                                      solution_type = "deSolve", quiet = TRUE),
        replications = 3)
      print(b.1)
      factor_SFO_SFO <- round(b.1["1", "relative"])
    } else {
      factor_SFO_SFO <- NA
      print("R package benchmark is not available")
    }

    ## Loading required package: rbenchmark

    ##                    test replications elapsed relative user.self sys.self
    ## 2      Eigenvalue based            3   2.814    1.309     2.812        0
    ## 3     deSolve, compiled            3   2.150    1.000     2.148        0
    ## 1 deSolve, not compiled            3  15.116    7.031    15.116        0
    ##   user.child sys.child
    ## 2          0         0
    ## 3          0         0
    ## 1          0         0

We see that using the compiled model is by a factor of around 7 faster than using the R version with the default ode solver, and it is even faster than the Eigenvalue based solution implemented in R which does not need iterative solution of the ODEs.

## Model that can not be solved with Eigenvalues

This evaluation is also taken from the example section of mkinfit.

    if (require(rbenchmark)) {
      FOMC_SFO <- mkinmod(
        parent = mkinsub("FOMC", "m1"),
        m1 = mkinsub( "SFO"))

      b.2 <- benchmark(
        "deSolve, not compiled" = mkinfit(FOMC_SFO, FOCUS_2006_D,
                                          use_compiled = FALSE, quiet = TRUE),
        "deSolve, compiled" = mkinfit(FOMC_SFO, FOCUS_2006_D, quiet = TRUE),
        replications = 3)
      print(b.2)
      factor_FOMC_SFO <- round(b.2["1", "relative"])
    } else {
      factor_FOMC_SFO <- NA
      print("R package benchmark is not available")
    }

    ## Successfully compiled differential equation model from auto-generated C code.

    ##                    test replications elapsed relative user.self sys.self
    ## 2     deSolve, compiled            3   3.661    1.000     3.660        0
    ## 1 deSolve, not compiled            3  31.110    8.498    31.108        0
    ##   user.child sys.child
    ## 2          0         0
    ## 1          0         0

Here we get a performance benefit of a factor of 8 using the version of the differential equation model compiled from C code!

This vignette was built with mkin 0.9.47.1 on

    ## R version 3.4.3 (2017-11-30)
    ## Platform: x86_64-pc-linux-gnu (64-bit)
    ## Running under: Debian GNU/Linux 9 (stretch)

    ## CPU model: Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz