У меня проблемы с производительностью моего кода. шаг # IIII
занимает часы времени. Раньше я материализовал itertools.prodct, но благодаря пользователю я больше не делаю pro_data = product(array_b,array_a)
. Это помогло мне с проблемами памяти, но по-прежнему требует много времени. Я хотел бы распараллелить его с помощью многопоточности или многопроцессорности, что бы вы ни предложили, я благодарен.
Объяснение. У меня есть два массива, которые содержат значения x и y частиц. Для каждой частицы (определяемой двумя координатами) я хочу вычислить функцию с другой. Для комбинаций я использую метод itertools.product и перебираю каждую частицу. Всего я запускаю более 50000 частиц, поэтому мне нужно рассчитать N * N/2 комбинаций.
заранее спасибо
import numpy as np
import matplotlib.pyplot as plt
from itertools import product,combinations_with_replacement
def func(ar1,ar2,ar3,ar4): #example func that takes four arguments
return (ar1*ar2**22+np.sin(ar3)+ar4)
def newdist(a):
return func(a[0][0],a[0][1],a[1][0],a[1][1])
x_edges = np.logspace(-3,1, num=25) #prepare x-axis for histogram
x_mean = 10**((np.log10(x_edges[:-1])+np.log10(x_edges[1:]))/2)
x_width=x_edges[1:]-x_edges[:-1]
hist_data=np.zeros([len(x_edges)-1])
array1=np.random.uniform(0.,10.,100)
array2=np.random.uniform(0.,10.,100)
array_a = np.dstack((array1,array1))[0]
array_b = np.dstack((array2,array2))[0]
# IIII
for i in product(array_a,array_b):
(result,bins) = np.histogram(newdist(i),bins=x_edges)
hist_data+=result
hist_data = np.array(map(float, hist_data))
plt.bar(x_mean,hist_data,width=x_width,color='r')
plt.show()
----- РЕДАКТИРОВАТЬ ----- Сейчас я использовал этот код:
def mp_dist(array_a,array_b, d, bins): #d chunks AND processes
def worker(array_ab, out_q):
""" push result in queue """
outdict = {}
outdict = vec_chunk(array_ab, bins)
out_q.put(outdict)
out_q = mp.Queue()
a = np.swapaxes(array_a, 0 ,1)
b = np.swapaxes(array_b, 0 ,1)
array_size_a=len(array_a)-(len(array_a)%d)
array_size_b=len(array_b)-(len(array_b)%d)
a_chunk = array_size_a / d
b_chunk = array_size_b / d
procs = []
#prepare arrays for mp
array_ab = np.empty((4, a_chunk, b_chunk))
for j in xrange(d):
for k in xrange(d):
array_ab[[0, 1]] = a[:, a_chunk * j:a_chunk * (j + 1), None]
array_ab[[2, 3]] = b[:, None, b_chunk * k:b_chunk * (k + 1)]
p = mp.Process(target=worker, args=(array_ab, out_q))
procs.append(p)
p.start()
resultarray = np.empty(len(bins)-1)
for i in range(d):
resultarray+=out_q.get()
# Wait for all worker processes to finish
for pro in procs:
pro.join()
print resultarray
return resultarray
Проблема здесь в том, что я не могу контролировать количество процессов. Как я могу использовать mp.Pool()
вместо этого? чем
newdist1
симметричен, вы можете вдвое сократить время, взяв каждую пару только один раз; 2) вы можете использоватьmultiprocessing
(неmultithreading
), чтобы распределить работу по нескольким процессам. Возможно, самым простым способом было бы иметьpool
процессов, где каждый получает значениеi
и ведет подсчет. В сети есть много примеров, так что просто попробуйте. 3) если этого недостаточно, то естьcython
. - person ev-br   schedule 07.03.2013combination_with_replacements
- person madzone   schedule 07.03.2013newdist
4 значения, из которых только 2 являются уникальными, там тоже может быть некоторая производительность для очистки. - person Jaime   schedule 07.03.2013