-1

I'm trying to functionalize the choice of a convergence criterion for an estimation algorithm that's going to loop through hundreds to thousands of Gibbs cycles; it needs to be calculated after each cycle. Shaving every millisecond helps as my sample increases. I'm looking for the fastest way to implement this "choice" of the user, using a logical to pick the estimate that is to be compared with the previous iteration. The results from these tests are not intuitive to me (within R... likely because I don't understand enough about "vectorization" and am being too optimistic in my assumptions). Can someone explain the results, cause it's making me think that I should stop trying to be creative and just keep doing the simplest thing possible, i.e. if {} else if {} else if {} else if {} else if ... else {}.

# Generate test data
xa<-rnorm(10000);xb<-rnorm(1000);xc<-rnorm(100);xd<-rnorm(10)
ya<-runif(10000);yb<-runif(1000);yc<-runif(100);yd<-runif(10)

# look at outputs; make choice
sapply(list(xa-ya,xb-yb,xc-yc,xd-yd),max)
test<-as.logical(c(0,0,0,1))

# Test 1
system.time(replicate(10000,{
  eps<-max(list(xa-ya,xb-yb,xc-yc,xd-yd)[[which(test)]])
}))
#user  system elapsed 
#0.14    0.12    0.27 

# Test 2
system.time(replicate(10000,{
  eps<-sapply(list(xa-ya,xb-yb,xc-yc,xd-yd),max)[test]
}))
#user  system elapsed 
#0.44    0.00    0.44 

# Test 3
system.time(replicate(10000,{
  if (test[1]) {
    eps<-max(xa-ya)
  } else if (test[2]) { 
    eps<-max(xb-yb)
  } else if (test[3]) {
    eps<-max(xc-yc)
  } else {
    eps<-max(xd-yd)
  }
}))
# user  system elapsed 
# 0.02    0.00    0.02 

Connected to the question, does it make sense to embed more if else statements in functions being called from the main trunk of the loop, or to make multiple functions for conditional "choices" and keep the if else statement in the main trunk?

quickreaction
  • 675
  • 5
  • 17
  • 1
    If you really want to be fast (and have to do this many times), use Rcpp. Four `if` is okay I think if you search for performance. – F. Privé Mar 10 '18 at 17:35

1 Answers1

0

I think you were mostly asking for an explanation of your timing results. (I don't think the explanation requires any invocation of vectorization but rather think the answer lies in consideration of the sequence of evaluations of expressions.) In all the situations except the last one, the code would have caused evaluation of all four of the subtraction expressions. And there would also have been the construction of a temporary object to hold the list of results. Only the last one would have avoided that process. When if (.){.} is evaluated and the antecedent is FALSE, there is no evaluation of the consequent. So only eps<-max(xd-yd) is evaluated. None of the other consequents were evaluated.

IRTFM
  • 258,963
  • 21
  • 364
  • 487