title: Is there an efficient way to parallelize mapply?
body: <p>I have many rows and on every row I compute the uniroot of a non-linear function. I have a quad-core Ubuntu machine which hasn't stopped running my code for two days now. Not surprisingly, I'm looking for ways to speed things up ;-)</p>
  
  <p>After some research, I noticed that only one core is currently used and parallelization is the thing to do. Digging deeper, I came to the conclusion (maybe incorrectly?) that the package <code>foreach</code> isn't really meant for my problem because too much overhead is produced (see, for example, <a href="https://stackoverflow.com/questions/5012804/mpi-parallelization-using-snow-is-slow">SO</a>). A good alternative seems to be <code>multicore</code> for Unix machines. In particular, the <code>pvec</code> function seems to be the most efficient one after I checked the help page.</p>
  
  <p>However, if I understand it correctly, this function only takes <strong>one</strong> vector and splits it up accordingly. I need a function that can be parallized, but takes <strong>multiple</strong> vectors (or a <code>data.frame</code> instead), just like the <code>mapply</code> function does. Is there anything out there that I missed?</p>
  
  <p>Here is a small example of what I want to do: (Note that I include a <code>plyr</code> example here because it can be an alternative to the base <code>mapply</code> function and it has a parallelize option. However, it is slower in my implementation and internally, it calls <code>foreach</code> to parallelize, so I think it won't help. Is that correct?)</p>
  
  <pre><code>library(plyr)
  library(foreach)
  n &lt;- 10000
  df &lt;- data.frame(P   = rnorm(n, mean=100, sd=10),
                   B0  = rnorm(n, mean=40,  sd=5),
                   CF1 = rnorm(n, mean=30,  sd=10),
                   CF2 = rnorm(n, mean=30,  sd=5),
                   CF3 = rnorm(n, mean=90,  sd=8))
  
  get_uniroot &lt;- function(P, B0, CF1, CF2, CF3) {
  
    uniroot(function(x) {-P + B0 + CF1/x + CF2/x^2 + CF3/x^3}, 
            lower = 1,
            upper = 10,
            tol   = 0.00001)$root
  
  }
  
  system.time(x1 &lt;- mapply(get_uniroot, df$P, df$B0, df$CF1, df$CF2, df$CF3))
     #user  system elapsed 
     #0.91    0.00    0.90 
  system.time(x2 &lt;- mdply(df, get_uniroot))
     #user  system elapsed 
     #5.85    0.00    5.85
  system.time(x3 &lt;- foreach(P=df$P, B0=df$B0, CF1=df$CF1, CF2=df$CF2, CF3=df$CF3, .combine = "c") %do% {
      get_uniroot(P, B0, CF1, CF2, CF3)})
     #user  system elapsed 
    # 10.30    0.00   10.36
  all.equal(x1, x2$V1) #TRUE
  all.equal(x1, x3)    #TRUE
  </code></pre>
  
  <p>Also, I tried to implement Ryan Thompson's function chunkapply from the SO link above (only got rid of <code>doMC</code> part, because I couldn't install it. His example works, though, even after adjusting his function.),
  but didn't get it to work. However, since it uses <code>foreach</code>, I thought the same arguments mentioned above apply, so I didn't try it too long.</p>
  
  <pre><code>#chunkapply(get_uniroot, list(P=df$P, B0=df$B0, CF1=df$CF1, CF2=df$CF2, CF3=df$CF3))
  #Error in { : task 1 failed - "invalid function value in 'zeroin'"
  </code></pre>
  
  <p>PS: I know that I could just increase <code>tol</code> to reduce the number of steps that are necessary to find a uniroot. However, I already set <code>tol</code> as big as possible.</p>