ra.png

Ra Timing Tests

Here is a table of timing tests. (These are for older versions of Ra. For more recent results look here.)
TestName                          --TimeInSecs---    -------Time/R---------
                                    R  ra04-nojit    ra04-nojit  ra03  ra04

convolve                          4.1         4.7           1.1   0.7   0.1
.TAOCP1997init from base/TAOCP.R  4.1         4.4           1.1   1.0   0.2
looped.dnorm                      6.7         7.3           1.1   0.6   0.2
simple.count x <- x + 1           4.7         5.2           1.1   0.7   0.4

vadim1 x[i] = x[i-1]              3.4         3.9           1.1   1.2   0.1
vadim2 x[i-1]                     5.0         5.6           1.1   0.7   0.3
vadim3 1                          4.2         4.5           1.1   1.1   1.1

vadim4 x[i] = 1.0                 4.7         5.1           1.1   1.2   0.1
vadim5 i-1                        5.2         5.7           1.1   0.4   0.4
vadim6 i                          4.4         5.3           1.2   1.2   1.2
For the specifics of each test see the code below.

The TimeInSecs column shows time in seconds for R 2.6.1 and ra04 without jitting.

The Time/R columns are the most interesting. They show the time taken by the Ra code divided by the R2.6.1 time. Successive runs give the same results give or take +-1 in the last digit. The measurements were made with on a 3 Ghz Pentium D running Windows XP. In jit.c, DEBUG_JIT=1 and DEBUG_SYM=1.

The tests tend to show the jitter in a good light. This is because they make heavy use of arithmetic with vectors in loops, do not call C or Fortran routines, and use a high number of loop iterations. Drop me a line if there are other tests you would like to see.

Here is the code to generate the results above. This code was run for the various configurations in the table. The relative times were then calculated manually using the R2.6.1 time as a reference.

# time-jit.R

# # dummy function for testing with standard R
# 
# jit <- function(jit=NA, trace=0)
# {
#     if (length(grep(" ra\\-", R.version.string)) > 0)
#         stop("Cannot redefine \"jit()\" when running ra")
#     c(jit, trace, jit)
# }

jit.flag <- 0
trace.flag <- 0
quick = 0       # 0 for full test, 1 for quick test
gctorture(0)

test <- function(f, N)
{
    strip.white.space <- function(s) gsub("[ \t\n]", "", s)

    jit.flag <<- 1; trace.flag <<- 0; time.jit    = system.time(a <- f(N))[1];
    jit.flag <<- 0; trace.flag <<- 0; time.no.jit = system.time(b <- f(N))[1];

    cat(sprintf("%-34.34s %5.2f    %5.2f %8.0f  %4.2f\n",
        paste(substitute(f)), time.no.jit, time.jit, N, time.jit / time.no.jit))

    stopifnot(identical(a, b))
}
convolve <- function(N) # from the extending R manual
{
    jit(jit.flag, trace.flag)
    a <- double(N)
    b <- double(N)
    na <- length(a)
    nb <- length(b)
    ab <- double(na + nb)
    for(i in 1:na)
        for(j in 1:nb)
             ab[i + j] <- ab[i + j] + a[i] * b[j]
    ab
}
# from base/TAOCP.R, a good test of integer arithmetic
.TAOCP1997init <- function(seed)
{
    jit(jit.flag, trace.flag)
    seed <- as.integer(seed)  # added for jit to prevent type change error
    KK <- 100L; LL <- 37L; MM <- as.integer(2^30)
    KKK <- KK + KK - 1L; KKL <- KK - LL
    ss <- seed - (seed %% 2L) + 2L
    X <- integer(KKK)
    for(j in 1L:KK) {
        X[j] <- ss
        ss <- ss+ss
        if(ss >= MM) ss <- ss - MM + 2L
    }
    X[2L] <- X[2L] + 1L
    ss <- seed
    T <- 69L
    while(T > 0) {
        for(j in KK:2L) X[j + j - 1L] <- X[j]
        for(j in seq(KKK, KKL + 1L, -2L))
            X[KKK - j + 2L] <- X[j] - (X[j] %% 2L)
        for(j in KKK:(KK+1L))
            if(X[j] %% 2L == 1L) {
                X[j - KKL] <- (X[j - KKL] - X[j]) %% MM
                X[j - KK] <- (X[j - KK] - X[j]) %% MM
            }
        if(ss %% 2L == 1L) {
            for(j in KK:1L) X[j + 1L] <- X[j]
            X[1L] <- X[KK + 1L]
            if(X[KK + 1L] %% 2L == 1L)
                X[LL + 1L] <- (X[LL + 1L] - X[KK + 1L]) %% MM
        }
        if(ss) ss <- ss %/% 2L else T <- T - 1L
    }
    rs <- c(X[(LL+1L):KK], X[1L:LL])
    invisible(rs)
}
`.TAOCP1997init from base/TAOCP.R` <- function(N)
{
    for (i in 1:N)
        .TAOCP1997init(N)
}
looped.dnorm <- function(N) # from one of Luke's compiler documents
{
    jit(jit.flag, trace.flag)
    mu <- 0
    sigma <- 1
    x <- 0
    for (i in 1:N)
        x <- x + (1/sqrt(2 * pi)) * exp(-0.5 * ((x - mu)/sigma)^2) / sigma
    x
}
`simple.count x <- x + 1` <- function(N)
{
    jit(jit.flag, trace.flag)
    x <- 0
    for(i in 1:N)
        x <- x+1
}
# Tests from Vadim Ogranovich post.
# See http://tolstoy.newcastle.edu.au/R/devel/05/04/0678.html
# Expressions are the same as the Luke's email reply except 
# that x and iA are local.

`vadim1 x[i] = x[i-1]` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N); x = double(N); x[1] = 1; x[2] = 2
    for (i in iA)
        x[i] = x[i-1]
    x
}
`vadim2 x[i-1]` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N); x = double(N); x[1] = 1; x[2] = 2
    for (i in iA)
        x[i-1]
    x
}
`vadim3 1` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N); x = double(N);
    for (i in iA)
        1
    x
}
`vadim4 x[i] = 1.0` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N); x = double(N); x[1] = 1; x[2] = 2
    for (i in iA)
        x[i] = 1.0
    x
}
`vadim5 i-1` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N);
    for (i in iA)
        i-1
    i
}
`vadim6 i` <- function(N)
{
    jit(jit.flag, trace.flag)
    iA = seq(2,N);
    for (i in iA)
        i
    i
}
cat("testname                           time  jit-time       N   reltime\n\n")
test(convolve, if (quick) 300 else 600)
test(`.TAOCP1997init from base/TAOCP.R`, if (quick) 5 else 20)
test(looped.dnorm, if (quick) 1e5 else 5e5)
N = as.integer(if (quick) 2e6 else 1e7)
# we adjust N below so each test takes about the same time
test(`simple.count x <- x + 1`, as.integer(N/3))
test(`vadim1 x[i] = x[i-1]`, N/20)
test(`vadim2 x[i-1]`, N/4)
test(`vadim3 1`, N*1.5)
test(`vadim4 x[i] = 1.0`, N/10)
test(`vadim5 i-1`, N/2)
test(`vadim6 i`, N*1.5)

To Ra homepage