У меня есть фрагмент следующего кода:
for x in xrange(100,14000):
for y in xrange(0,3000):
for z in xrange(0,700):
operationg_tag = "%s-%s-%s" % (x,y,z)
operation_code = ....
and more bunch of code is running here on the tag generated above
Я запускаю этот код на быстром хорошем оборудовании, но природа этих циклов медленная, потому что они не работают в многопроцессорной / многопоточности
Выполнение необходимого кода для каждого тега занимает около 0,4 секунды.
Как я могу реализовать многопроцессорность / многопоточность в этих вложенных циклах, чтобы они работали быстрее? на какую из петель я должен нацеливаться?
Попробуйте несколько разных подходов и посмотрите, что работает. это не бесплатная услуга кодирования.
Является ли многопроцессорность хорошей идеей (или даже лучше, чем многопоточность) определенно зависит от связка кода, который работает здесь. Какой код там работает? Это тип кода, который блокирует GIL? Это код, который принимает много данных на входе и / или возвращает много данных на выходе?
@zvone По большей части это чтение файла (~ 100 КБ) и анализ данных из него. это примерно 8 строк для этой функции.
@rootameen Доступ к файлу не блокирует GIL. Парсинг (в python) делает. Что вы делаете с проанализированными данными? Вам нужно вернуть много данных вызывающей функции? Если нет (например, если вы просто сохраняете результаты в другой файл), кажется совершенно логичным разделить это на отдельные процессы, которые просто принимают x, y, z в качестве входных данных и ничего не возвращают в качестве выходных данных. Вопрос о вводе / выводе важен, потому что основная проблема многопроцессорной обработки - это связь между ними.






Разбейте первый цикл как 3 процесса,
def func(start, final):
for x in xrange(start, final):
for y in xrange(0,3000):
for z in xrange(0,700):
operationg_tag = "%s-%s-%s" % (x,y,z)
operation_code = ....
def main():
total = 14000
div_total = int(14000 / 3)
rest_div_total = 14000%3
t1 = multiprocessing.Process(target = func,name = "", args=(100, div_total)
t2 = multiprocessing.Process(target = func,name = "", args=(div_total, div_total*2)
t3 = multiprocessing.Process(target = func,name = "", args=(div_total*2, div_total*3 + rest_div_total + 1)
list_threads = [t1,t2,t3]
for i in list_threads:
i.start()
for i in list_threads:
i.join()
if __name__ == "__main__":
main()
Вы можете создать больше процессов, если хотите, но 3 Это хорошо.
Спасибо @Joao, я немного изменил ваш main, добавив больше потоков, и это дает мне желаемый результат.
# 1, многопоточность здесь совершенно не поможет. Он должен быть многопроцессорным. # 2, это зависит от вашего оборудования, количества ядер, задержек шины и т. д.