R: Byte Code Compiler

compile {compiler} | R Documentation

## Byte Code Compiler

### Description

These functions provide an interface to a byte code compiler for R.

### Usage

    cmpfun(f, options = NULL)
    compile(e, env = .GlobalEnv, options = NULL)
    cmpfile(infile, outfile, ascii = FALSE, env = .GlobalEnv,
            verbose = FALSE, options = NULL)
    loadcmp(file, envir = .GlobalEnv, chdir = FALSE)
    disassemble(code)
    enableJIT(level)
    compilePKGS(enable)
    getCompilerOption(name, options)
    setCompilerOptions(...)

### Arguments

`f` | a closure.
`options` | list of named compiler options
`env` | the top level environment for the compiling.
`file,infile,outfile` | pathnames; outfile defaults to infile with a .Rc extension in place of any existing extension.
`ascii` | logical; should the compiled file be saved in ascii format?
`verbose` | logical; should the compiler show what is being compiled
`envir` | environment to evaluate loaded expressions in.
`chdir` | logical; change directory before evaluation?
`code` | byte code expression or compiled closure
`e` | expression to compile
`level` | integer; the JIT level to use
`enable` | logical; enable compiling packages if `TRUE`
`name` | character string; name of option to return
`...` | named compiler options to set

### Details

The function `cmpfun` compiles the body of a closure and returns a new closure with the same formals and the body replaced by the compiled body expression.

`compile` compiles an expression into a byte code object; the object can then be evaluated with `eval`.

`cmpfile` parses the expression in `infile`, compiles them, and writes the compiled expressions to `outfile`. If `outfile` is not provided, it is formed from `infile` by replacing or appending a `.Rc` suffix.

`loadcmp` is used to load compiled files. It is similar to `sys.source`, except that its default loading environment is the global environment rather than the base environment.

`disassemble` produces a printed representation of the code that may be useful to give a hint of what is going on.

`enableJIT` enables or disables just-in-time (JIT) compilation. JIT is disabled if the argument is 0. If `enable` is 1 then closures are compiled before their first use. If `enable` is 2, then in addition closures are also compiled before they are duplicated (useful for some packages, like `lattice`, that store closures in lists). If `enable` is 3 then in addition all loops are compiled before they are executed. JIT can also be enabled by starting R with the environment variable `R_ENABLE_JIT` set to one of these values.

`compilePKGS` enables or disables compiling packages when they are installed. This requires that the package use lazy loading as compilation occurs as functions are written to the lazy loading data base. This can also be enabled by starting R with the environment variable `R_COMPILE_PKGS` set to a positive integer value.

Currently the compiler warns about a variety of things. It does this by using `cat` to print messages. Eventually this should use the condition handling mechanism.

The `options` argument can be used to control compiler operation. There are currently three options: `optimize`, `suppressAll`, and `suppressUndefined`. `optimize` specifies the optimization level, which can be an integer form 0 to 3. `suppressAll` should be a scalar logical; if `TRUE` no messages will be shown. `suppressUndefined` can be `TRUE` to suppress all messages about undefined variables, or it can be a character vector of the names of variables for which messages should not be shown.

`getCompilerOption` returns the value of the specified option. The default value is returned unless a value is supplied in the `options` argument; the `options` argument is primarily for internal use. `setCompilerOption` sets the default option values. It returns a named list of the previous values.

Calling the compiler a byte code compiler is actually a bit of a misnomer: the external representation of code objects currently uses `int` operands, and when compiled with `gcc` the internal representation is actually threaded code rather than byte code.

### Author(s)

Luke Tierney

### Examples

    # a simple example
    f <- function(x) x+1
    fc <- cmpfun(f)
    fc(2)
    disassemble(fc)

    # old R version of lapply
    la1 <- function(X, FUN, ...) {
        FUN <- match.fun(FUN)
        if (!is.list(X))
    	X <- as.list(X)
        rval <- vector("list", length(X))
        for(i in seq(along = X))
    	rval[i] <- list(FUN(X[[i]], ...))
        names(rval) <- names(X)		  # keep `names' !
        return(rval)
    }
    # a small variation
    la2 <- function(X, FUN, ...) {
        FUN <- match.fun(FUN)
        if (!is.list(X))
    	X <- as.list(X)
        rval <- vector("list", length(X))
        for(i in seq(along = X)) {
            v <- FUN(X[[i]], ...)
            if (is.null(v)) rval[i] <- list(v)
            else rval[[i]] <- v
        }
        names(rval) <- names(X)		  # keep `names' !
        return(rval)
    }
    # Compiled versions
    la1c <- cmpfun(la1)
    la2c <- cmpfun(la2)
    # some timings
    x <- 1:10
    y <- 1:100

    system.time(for (i in 1:10000) lapply(x, is.null))
    system.time(for (i in 1:10000) la1(x, is.null))
    system.time(for (i in 1:10000) la1c(x, is.null))
    system.time(for (i in 1:10000) la2(x, is.null))
    system.time(for (i in 1:10000) la2c(x, is.null))
    system.time(for (i in 1:1000) lapply(y, is.null))
    system.time(for (i in 1:1000) la1(y, is.null))
    system.time(for (i in 1:1000) la1c(y, is.null))
    system.time(for (i in 1:1000) la2(y, is.null))
    system.time(for (i in 1:1000) la2c(y, is.null))

[Package compiler version 3.1.2 Index]