title: Parralelized code runs much slower in Python than in Matlab
body: <p>I have a piece of code that does the following:</p>
  
  <pre><code>for each file (already read in the RAM):
      call a function and obtain a result
  add the results up and disply
  </code></pre>
  
  <p>Each file can be analyzed in parallel. The function that analyzes each file is as following:</p>
  
  <pre><code># Complexity = 1000*19*19 units of work
  def fun(args):
      (a, b, p) = args
      for itr in range(1000):
          for i in range(19):
              for j in range(19):
                  # The following random number generated depends on
                  # latest values in (i-1, j), (i+1, j), (i, j-1) &amp; (i, j+1)
                  # cells of latest a and b arrays
                  u = np.random.rand();
                  if (u &lt; p):
                      a[i, j] += -1
                  else:
                      b[i, j] += 1
      return a+b
  </code></pre>
  
  <p>I am using <code>multiprocessing</code> package to achieve parallelism:</p>
  
  <pre><code>import numpy as np
  import time
  from multiprocessing import Pool, cpu_count
  
  if __name__ == '__main__':
      t = time.time()
      pool = Pool(processes=cpu_count())
      args = [None]*100
      for i in range(100):
          a = np.random.randint(2, size=(19, 19))
          b = np.random.randint(2, size=(19, 19))
          p = np.random.rand()
          args[i] = (a, b, p)
      result = pool.map(fun, args)
      for i in range(2, 100):
          result[0] += result[i]
      print result[0]
      print time.time() - t
  </code></pre>
  
  <p>I have written equivalent <code>MATLAB</code> code that uses <code>parfor</code> and calls <code>fun</code> in each iteration of <code>parfor</code>:</p>
  
  <pre><code>tic
  args = cell(100, 1);
  r = cell(100, 1);
  parfor i = 1:100
     a = randi(2, 19, 19);
     b = randi(2, 19, 19);
     p = rand();
     args{i}.a = a;
     args{i}.b = b;
     args{i}.p = p;
     r{i} = fun(args{i});
  end
  
  for i = 2:100
      r{1} = r{1} + r{i};
  end
  disp(r{1});
  toc
  </code></pre>
  
  <p>The implementation of <code>fun</code> is as follows:</p>
  
  <pre><code>function [ ret ] = fun( args )
  a = args.a;
  b = args.b;
  p = args.p;
  
  for itr = 1:1000
      for i = 1:19
          for j = 1:19
              u = rand();
              if (u &lt; p)
                  a(i, j) = a(i, j) + -1;
              else
                  b(i, j) = b(i, j) + 1;
              end
          end
      end
  end
  ret = a + b;
  end
  </code></pre>
  
  <p>I find that <code>MATLAB</code> is blazingly fast, it takes around 1.5 seconds on a dual core processor compared to around 33-34 seconds taken by <code>Python</code> program. Why is this so?</p>
  
  <p>EDIT: A lot of answers suggested that I should vectorize the random number generation. Actually the way it works is, random number generated depends on the latest a and b 2D arrays. I just put a simple <code>rand()</code> call to keep program simple and readable. In actuality of my program, random number is always generated by looking at certain horizontally and vertically neighbouring cells of (i, j) cell. So it is not possible to vectorize that.</p>