import time
import multiprocessing

def processSlice(id, sliceSize, delta):
    sum = 0.0
    for i in xrange (1 + id * sliceSize, (id + 1) * sliceSize + 1) :
        x = (i - 0.5) * delta
        sum += 1.0 / (1.0 + x * x)
    return sum

def execute_nonParallel():
   n = 10000000
   delta = 1.0 / n
   sliceSize = n
   results = processSlice(0,sliceSize,delta)
   print(results * 4.0 * delta)

def execute(processCount,pool) :
    n = 10000000
    delta = 1.0 / n
    sliceSize = n / processCount
    startTime = time.time()
    results = [pool.apply_async(processSlice,args = (i,sliceSize,delta)) for i in xrange(0,processCount)]
    results = [item.get() for item in results]
    pi = 4.0 * sum(results) * delta
    elapseTime = time.time() - startTime
    print("==== Python Multiprocessing Pool pi = " + str(pi))
    print("==== Python Multiprocessing Pool iteration count = "+ str(n))
    print("==== Python Multiprocessing Pool elapse = " + str(elapseTime))
    print("==== Python Multiprocessing Pool process count = " + str(processCount))
    print("==== Python Multiprocessing Pool processor count = " + str(multiprocessing.cpu_count()))
    print

if __name__ == '__main__' :
   startTime = time.time()
   execute_nonParallel()
   print('non parallel execution time: ' + str(time.time() - startTime))
   startTime = time.time()
   pool = multiprocessing.Pool(processes=8)
   print('pool creation time: ' + str(time.time() - startTime))
   execute(1,pool)
   print
   execute(1,pool)
   print
   execute(2,pool)
   print
   execute(4,pool)
   print
   execute(8,pool)
   print
   pool.close()
