Reputation: 11
I hope this is not a duplicate question.
I've run the same function in Python 3.4.2 in a simple way and in a multi-processing way and I've found that the simple way is faster. Perhaps my design is not good, but I don't see where the problem lies.
Below is my code:
Common part
import os
import math
from multiprocessing import Process
import timeit
def exponential(number):
"""
A function that returns exponential
"""
result = math.exp(number)
proc = os.getpid()
Simple solution
if __name__ == '__main__':
start = timeit.default_timer()
numbers = [5, 10, 20, 30, 40, 50, 60]
for index, number in enumerate(numbers):
exponential(number)
stop = timeit.default_timer()
duration = stop - start
print(duration)
Multi-processing solution
if __name__ == '__main__':
start = timeit.default_timer()
numbers = [5, 10, 20, 30, 40, 50, 60]
procs = []
for index, number in enumerate(numbers):
proc = Process(target=exponential, args=(number,))
procs.append(proc)
proc.start()
for proc in procs:
proc.join()
stop = timeit.default_timer()
duration = stop - start
print(duration)
What I see is that the simple solution is faster than the multi-processing one:
Duration with Simple solution: 2.8359994757920504e-05
Duration with Multi processing solution: 0.012581961986143142
Upvotes: 1
Views: 82
Reputation: 113915
Computing math.exp(x)
, where x<100 (as it is in your case) is not especially difficult. So you don't computing these in parallel does not offer a clear advantage.
Remember that when you set up multiple processes, you also incur the overhead of creating a new process, and copying over the memory space, etc.
Finally, there's something to be said about you creating a new process for each number in that list. If that list had 100 numbers in it, you'd be creating 100 new processes, which will compete for time on your 4 or 8 cores (depending on your CPU), which will add to further delays (especially when the computation itself gets complex). You're better off creating a pool of processes and getting them to incrementally work on your dataset:
import math
import multiprocess as mp
def slave(qIn, qOut):
for i, num in iter(qIn.get, None):
qOut.put((i, math.exp(num))
qOut.put(None)
def master():
numbers = [5, 10, 20, 30, 40, 50, 60]
qIn, qOut = [mp.Queue() for _ in range(2)]
procs = [mp.Process(target=slave, args=(qIn, qOut)) for _ in range(mp.cpu_count()-1)]
for p in procs: p.start()
for t in enumerate(numbers): qIn.put(t)
for p in procs: qIn.put(None)
answer = [None] * len(numbers)
done = 0
while done < len(numProcs):
t = qOut.get()
if t is None:
done += 1
continue
i, e = t
answer[i] = e
for p in procs: p.terminate()
return answer
Upvotes: 1