Wąskim gardłem prędkości w moim kodzie jest ciasna podwójna pętla nad elementami dwóch tablic, x i y. Standardową sztuczką hpc do poprawy wydajności jest wykonywanie pętli w porcjach, aby można było zminimalizować chybienia pamięci podręcznej. Próbuję użyć generatorów Pythona do robienia kawałków, ale potrzeba ciągłego odtwarzania zużytego generatora w zewnętrznej pętli fora zabija moje środowisko uruchomieniowe.Efektywne wykorzystanie generatorów python w ciasnej podwójnej pętli nad liczbowymi tablicami
Pytanie:
Czy jest bardziej inteligentny algorytm konstruowania odpowiedni generator for the Performing pakietowego podwójnej pętli?
ilustracja Beton:
będę tworzyć dwie tablice obojętne, x i y. Będę trzymać je za ilustrację, ale w praktyce są to numpy tablice z ~ 1e6 elementami.
x = np.array(['a', 'b', 'b', 'c', 'c', 'd'])
y = np.array(['e', 'f', 'f', 'g'])
Naiwny podwójnej pętli będzie tylko:
for xletter in x:
for yletter in y:
# algebraic manipulations on x & y
Teraz użyjmy generatory to zrobić pętlę w kawałkach:
chunk_size = 3
xchunk_gen = (x[i: i+chunk_size] for i in range(0, len(x), chunk_size))
for xchunk in xchunk_gen:
ychunk_gen = (y[i: i+chunk_size] for i in range(0, len(y), chunk_size))
for ychunk in ychunk_gen:
for xletter in xchunk:
for yletter in ychunk:
# algebraic manipulations on x & y
pamiętać, że w celu wdrożenia rozwiązania generatora do tego problemu, muszę ciągle odtwarzać ychunk_gen w zewnętrznej pętli. Ponieważ y jest dużą tablicą, to zabija moje środowisko uruchomieniowe (dla ~ 1e6 elementów, stworzenie tego generatora zajmuje ~ 20ms na moim laptopie).
Czy istnieje sposób, aby być bardziej sprytnym na temat tego, w jaki sposób konstruuję generatory, które radzą sobie z tym problemem? A może trzeba będzie po prostu całkowicie zrezygnować z rozwiązania generatora?
(Uwaga: W praktyce używam cythonu do wykonania tej ciasnej pętli, ale wszystkie powyższe zasady obowiązują niezależnie).
Jeśli 'x' i' y' są listami w pamięci RAM to używanie generatorów podobnych do twoich nie przynosi żadnych korzyści ... możesz też uruchomić 'counter = len (x) * len (y)' –
Czy próbowałeś używać wyrażeń listowych zamiast wyrażeń generatora i tworzenia obu list kawałków przed zewnętrzną pętlą? –
Czy możesz nam powiedzieć, co właściwie robisz w swojej prawdziwej pętli i jakie jest twoje rzeczywiste zadanie? Być może możemy zapewnić lepszą pomoc, jeśli zobaczymy duży obraz. –