[R] Speedups with Ra and jit

Bill.Venables at csiro.au Bill.Venables at csiro.au
Fri May 2 02:52:43 CEST 2008


The topic of Ra and jit has come up on this list recently

(see http://www.milbo.users.sonic.net/ra/index.html)

so I thought people might be interested in this little demo. For it I
used my machine, a 3-year old laptop with 2Gb memory running Windows
XP, and the good old convolution example, the same one as used on the
web page, (though the code on the web page has a slight glitch in it).

This is using Ra with R-2.7.0.

> conv1 <- function(a, b) {  
> ### with Ra and jit
      require(jit)
      jit(1)
      ab <- numeric(length(a)+length(b)-1)
      for(i in 1:length(a))
        for(j in 1:length(b))
          ab[i+j-1] <- ab[i+j-1] + a[i]*b[j]
      ab
    }
> 
> conv2 <- function(a, b) {
> ### with just Ra
      ab <- numeric(length(a)+length(b)-1)
      for(i in 1:length(a))
        for(j in 1:length(b))
          ab[i+j-1] <- ab[i+j-1] + a[i]*b[j]
      ab
    }
> 
> x <- 1:2000
> y <- 1:500
> system.time(tst1 <- conv1(x, y))
   user  system elapsed 
   0.53    0.00    0.55 
> system.time(tst2 <- conv2(x, y))
   user  system elapsed 
   9.49    0.00    9.56 
> all.equal(tst1, tst2)
[1] TRUE
>
> 9.56/0.55
[1] 17.38182
> 

However for this example you can achieve speed-ups like that or better
just using vectorised code intelligently:

> conv3 <- local({
      conv <- function(a, b, na, nb) {
        r <- numeric(na + nb -1)
        ij <- 1:nb
        for(e in a) {
          r[ij] <- r[ij] + e*b
          ij <- ij + 1
        }
        r
      }
    
      function(a, b) {
        na <- length(a)
        nb <- length(b)
        if(na < nb) conv(a, b, na, nb) else
                    conv(b, a, nb, na)
      }
    })
> 
> system.time(tst3 <- conv3(x, y))
   user  system elapsed 
   0.11    0.00    0.11 
> all.equal(tst1, tst3)
[1] TRUE

> 0.55/0.11
[1] 5
> 9.56/0.11
[1] 86.90909

ie. a further 5-fold increase in speed, or about 87 times faster than
the unassisted naïve code.

I think the lesson here is if you really want to write R code as you
might C code, then jit can help make it practical in terms of time.
On the other hand, if you want to write R code using as much of the
inbuilt operators as you have, then you can possibly still do things
better.

Of course sometimes you don't have the right inbuilt operators.  In
that case you have a three-way choice: slow R code and wait, faster R
code speeded up with Ra and jit, or, (the way it probably should be
done), with dynamically loaded C or Fortran code.  Portability
decreases as you go, of course.


Bill Venables



More information about the R-help mailing list