Python Multithreading vs Multiprocessing vs Sequential Execution
<p>I have the below code:</p>

<pre><code>import time
from threading import Thread
from multiprocessing import Process 

def fun1():

 for _ in xrange(10000000):
        print 'in fun1'
        pass

def fun2():

 for _ in xrange(10000000):
        print 'in fun2'
        pass

def fun3():

 for _ in xrange(10000000):
        print 'in fun3'
        pass

def fun4():

 for _ in xrange(10000000):
        print 'in fun4'
        pass

if __name__ == '__main__':

  #t1 = Thread(target=fun1, args=())
  t1 = Process(target=fun1, args=())
  #t2 = Thread(target=fun2, args=())
  t2 = Process(target=fun2, args=())
  #t3 = Thread(target=fun3, args=())
  t3 = Process(target=fun3, args=())
  #t4 = Thread(target=fun4, args=())
  t4 = Process(target=fun4, args=())
  t1.start()
  t2.start() 
  t3.start() 
  t4.start()
  start = time.clock()
  t1.join()
  t2.join()
  t3.join()
  t4.join()
  end = time.clock()
  print("Time Taken = ",end-start)

  '''
  start = time.clock()
  fun1()
  fun2()
  fun3()
  fun4()
  end = time.clock()
  print("Time Taken = ",end-start)
  '''
</code></pre>

<p>I ran the above program in three ways:</p>

<ul>
<li>First Sequential Execution ALONE(look at the commented code and comment the upper code)</li>
<li>Second Multithreaded Execution ALONE</li>
<li>Third Multiprocessing Execution ALONE</li>
</ul>

<p>The observations for end_time-start time are as follows:</p>

<p>Overall Running times</p>

<ul>
<li>('Time Taken = ', <strong>342.5981313667716</strong>) --- Running time by <strong>threaded execution</strong></li>
<li>('Time Taken = ', <strong>232.94691744899296</strong>) --- Running time by <strong>sequential Execution</strong></li>
<li>('Time Taken = ', <strong>307.91093406618216</strong>) --- Running time by <strong>Multiprocessing execution</strong></li>
</ul>

<p><strong>Question :</strong> </p>

<p>I see sequential execution takes least time and Multithreading takes highest time. Why? I am unable to understand and also surprised by results.Please clarify.</p>

<p>Since this is a CPU intensive task and GIL is acquired, my understanding was 
Multiprocessing would take least time while threaded execution would take highest time.Please validate my understanding. </p>

<p>You use <code>time.clock</code>, wich gave you CPU time and not real time : you can't use that in your case, as it gives you the execution time (how long did you use the CPU to run your code, wich will be almost the same time for each of these case)</p>

<p>Running your code with <code>time.time()</code> instead of <code>time.clock</code> gave me these time on my computer : </p>

<pre><code>Process : ('Time Taken = ', 5.226783990859985)
seq : ('Time Taken = ', 6.3122560000000005)
Thread :  ('Time Taken = ', 17.10062599182129)
</code></pre>

<p>The task given here (printing) is so fast that the speedup from using multiprocessing is almost balanced by the overhead.</p>

<p>For <code>Threading</code>, as you can only have one Thread running because of the GIL, you end up running all your functions sequentially BUT you had the overhead of threading (changing threads every few iterations can cost up to several milliseconds each time). So you end up with something much slower.</p>

<p><code>Threading</code> is usefull if you have waiting times, so you can run tasks in between.</p>

<p><code>Multiprocessing</code> is usefull for computationnally expensive tasks, if possible completely independant (no shared variables). If you need to share variables, then you have to face the GIL and it's a little bit more complicated (but not impossible most of the time).</p>

<p>EDIT : Actually, using <code>time.clock</code> like you did gave you the information about how much overhead using <code>Threading</code> and <code>Multiprocessing</code> cost you.</p>

python multithreading python-2.7 multiprocessing