title: rust vs c performance
body: <p>I wanted to learn a bit about rust tasks, so I did a monte carlo computation
  of PI. Now my puzzle is why the single-threaded C version is 4 times faster
  than the 4-way threaded Rust version.  Clearly I am doing something wrong, or my mental performance model is way off. </p>
  
  <p>Here's the C version:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdio.h&gt;
  
  #define PI 3.1415926535897932
  
  double monte_carlo_pi(int nparts)
  {
      int i, in=0;
      double x, y;
      srand(getpid());
  
      for (i=0; i&lt;nparts; i++) {
          x = (double)rand()/(double)RAND_MAX;
          y = (double)rand()/(double)RAND_MAX;
  
              if (x*x + y*y &lt; 1.0) {
              in++;
          }
      }
  
      return in/(double)nparts * 4.0;
  }
  
  int main(int argc, char **argv)
  {
      int nparts;
      double mc_pi;
  
      nparts = atoi(argv[1]);
      mc_pi = monte_carlo_pi(nparts);
      printf("computed: %f error: %f\n", mc_pi, mc_pi - PI);
  }
  </code></pre>
  
  <p>The Rust version was not a line-by-line port:</p>
  
  <pre><code>use std::rand;
  use std::rand::distributions::{IndependentSample,Range};
  
  fn monte_carlo_pi(nparts: uint ) -&gt; uint {
      let between = Range::new(0f64,1f64);
      let mut rng = rand::task_rng();
      let mut in_circle = 0u;
      for _ in range(0u, nparts) {
          let a = between.ind_sample(&amp;mut rng);
      let b = between.ind_sample(&amp;mut rng);
  
      if a*a + b*b &lt;= 1.0 {
          in_circle += 1;
      }
      }
      in_circle
  }
  
  fn main() {
      let (tx, rx) = channel();
  
      let ntasks = 4u;
      let nparts = 100000000u; /* I haven't learned how to parse cmnd line args yet!*/
      for _ in range(0u, ntasks) {
          let child_tx = tx.clone();
          spawn(proc() {
          child_tx.send(monte_carlo_pi(nparts/ntasks));
          });
      }
  
      let result = rx.recv() + rx.recv() + rx.recv() + rx.recv();
  
      println!("pi is {}", (result as f64)/(nparts as f64)*4.0);
  }
  </code></pre>
  
  <p>Build and time the C version:</p>
  
  <pre><code>$ clang -O2 mc-pi.c -o mc-pi-c; time ./mc-pi-c 100000000
  computed: 3.141700 error: 0.000108
  ./mc-pi-c 100000000  1.68s user 0.00s system 99% cpu 1.683 total
  </code></pre>
  
  <p>Build and time the Rust version:</p>
  
  <pre><code>$ rustc -v      
  rustc 0.12.0-nightly (740905042 2014-09-29 23:52:21 +0000)
  $ rustc --opt-level 2 --debuginfo 0 mc-pi.rs -o mc-pi-rust; time ./mc-pi-rust  
  pi is 3.141327
  ./mc-pi-rust  2.40s user 24.56s system 352% cpu 7.654 tota
  </code></pre>