Есть код на питоне как можно ускорить его мультипроцессность не работает?

код:
import multiprocessing
import itertools

lst = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']

def gen(args):
	count=0
	for x in itertools.product(lst,repeat = 16):
		key=''
		key+= "{}{}".format(3,''.join(x))
		count+=1
		print(key,count,end='\r')


if __name__ == '__main__':
	p = multiprocessing.Process(target=gen,args=(lst,))
	p.start()
	p.join()

но он медленно работает как его можно ускорить до миллион комбинации в секунду можете помочь как нибудь
  • Вопрос задан
  • 235 просмотров
Пригласить эксперта
Ответы на вопрос 3
AshBlade
@AshBlade
Просто хочу быть счастливым
Здесь только 1 процесс по факту работает , параллелизации нет.

Для оптимизации можешь распараллелить по первому индексу старта начала комбинации.
Например, один процесс обрабатывает комбинации начиная с 0 по 4, другой с 5 по 9 и т.д.
Ответ написан
Vindicar
@Vindicar
RTFM!
p = multiprocessing.Process(target=gen,args=(lst,))
p.start()

Ты запускаешь ровно один процесс, а потом стоишь и ждёшь (p.join()), когда он завершится. Это мало чем отличается от просто вызова gen() в твоём коде, безо всякого мультипроцессинга.
Кроме того, у тебя функция gen() делает всю работу, а должна обрабатывать только один элемент. Ты думаешь Питон волшебным образом поймёт, что вот именно этот цикл надо распараллелить?

Используй пул процессов multiprocessing.Pool, он принимает функцию и последовательность входных значений, а потом скармливает эти значения по одному в копии указанной функции в нескольких процессах, и собирает из них ответы.

Пример есть в документации, если ты туда заглядывал. В примере показано несколько вариантов использования пула процессов.
Я бы на твоём месте использовал или imap_unordered(), или imap(). Разница в том, что первый может не сохранять порядок - т.е. результаты тебе будут приходить не в том же порядке, в каком приходили данные во входной последовательности. Второй его сохраняет, но работает чуть медленнее (он ждёт, пока правильный порядок не получится).
Ответ написан
mayton2019
@mayton2019
Bigdata Engineer
Вот в один поток на сях. Только сам скомпилируй. 32 млн строк в секунду. Если писать в /dev/null

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// habr.com : mayton2019 - 3 Sep 2023

char *hex = "0123456789abcdef";
char *buf;

void streamer(int max_depth, int level, char *alphabet, int alphabet_size) {
   for(int i = 0 ; i < alphabet_size ; i++) {
      buf[level] = alphabet[i];   
      if ( level < max_depth ) {
        streamer(max_depth, level+1, alphabet, alphabet_size);
      } else {
        buf[level] = '\0';
        printf("%s\n", buf);
        break;
      }
   }
}

int main(int argc, char** argv) {
  buf = malloc(strlen(hex) + 1);
  streamer(16, 0, hex, strlen(hex));
  free(buf);
  return 0;
}


Вот как я мерял.
gcc hex-gen.c -o hex-gen.exe && ./hex-gen.exe | pv -l -r > /dev/null
[30.7M/s]
[30.1M/s]
[30.3M/s]


Вот если писать в текстовый файл то скорость чуть медленнее. 24 млн строк за секунду.

Вот. Проверяй данные. Что я нигде не ошибся.

UPD: Лишний ноль убрал.
UPD: +break добавил.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы