Jak zmienic ten kod na szybszy?

Odpowiedz Nowy wątek
2019-02-10 13:16
0

Witam,
Mam tutaj proste wczytywanie pliku:

with open("scan/scan.txt") as file:
        for line in file:
                check(line)

Problem jest taki ze plik ma ok 50000 linijek.
Jak można usprawnić ten kod zeby działał szybciej? Multiprocessing? Nigdy nie robiłem programu który wykorzystuje multi threading-processing.

Pozostało 580 znaków

2019-02-10 18:12
Adrian Rudy Dacka napisał(a):

Akurat nie mogę wysłać 10 linijek gdyż nie każda idzie do jednego serwera. Jest to tylko fragment funkcji check. Niektóre linijki zawierające konkretną wartość idą na inny serwer a inne na inny,funkcja check przed wysłaniem je dzieli i wysyła na serwer.

Rozwiązanie jest dość proste:

Skoro linijki w zależności od zawartości wysyłane są na różne serwery, i i tak musisz to określić na podstawie zawartości linijki - pogrupuj je według tej zawartości na paczki tak, by każda paczka była wysyłana na jeden, konkretny serwer.

Ktoś tu linkował moduł pandas - tak się składa, że pandas.DataFrame dostarcza Ci praktycznie wszystkich narzędzi niezbędnych do wykonania tego grupowania. Możesz nawet pogrupować swoje dane wg. serwera docelowego, po czym odpalić osobne procesy, z których każdy będzie gadał z osobnym serwerem z puli, jeśli koniecznie chcesz. Wczytywać dane z obiektów dict czy plików json też potrafi.

Ale skoro Twój program działa tak szybko, jak tylko pozwala na to Twoja sieć, to musisz podjąć kroki, które sieć odciążą - dopiero wtedy będziesz mógł kombinować nad dalszym przyspieszaniem. Optymalizację zaczynaj od identyfikacji i eliminacji wąskich gardeł - Twoim najwyraźniej jest narzut komunikacji po sieci.

Staraj się wyeliminować wszystko, co nie jest absolutnie niezbędne do działania programu:

  • wielokrotne nawiązywanie i zamykanie połączeń z jednym serwerem - nawet głupi 3-way handshake TCP (nie wskazałeś, czy łączysz się po gołym TCP, UDP - w UDP wręcz wcale się nie łączysz, bo to protokół bezpołączeniowy, HTTP, websockets, MQTT czy jeszcze czymś innym) będzie powodował jakiś narzut. Jeśli nawiążesz jedno połączenie z każdym serwerem i wykorzystasz je 1000 razy, zmniejszysz czas nawiązywania połączeń 1000 razy - być może zyskasz tylko 1s, być może aż 4s - sprawdź.
  • nadmierne rozdrabnianie przesyłanych danych - ok, może i daje nieco płynniejszą komunikację, szczególnie, jeśli coś ma się dziać real-time. Ale w niektórych przypadkach będzie powodować nadmierny narzut, szczególnie, gdy będziesz miał bardzo dużo, bardzo krótkich komunikatów. To zależy również od tego, jak protokół, który wykorzystujesz do komunikacji, traktuje danych - jako ciągły strumień czy niezależne datagramy/komunikaty. Spróbuj wysłać więcej danych w jednym komunikacie i sprawdź co się stanie. Może się okazać, że to jest właśnie to i będziesz musiał zrezygnować z wysyłania wierszy pojedynczo, jeśli będziesz chciał uzyskać jakiekolwiek zauważalne przyspieszenie.
  • synchroniczne oczekiwanie na odpowiedź z serwera - tak, to też może spowolnić, i możesz faktycznie uzyskać szybsze wykonanie, ale głównie dzięki asynchronicznemu wykonaniu. Spróbuj skorzystać z modułu concurrent.futures i możliwości pobierania wyników z obiektów Future. Zyskasz na tym o tyle, że podczas gdy jeden proces musi wykonać w korku pętli następujące kroki:

    • wysyłanie komunikatu (upload zatkany)
    • oczekiwanie na odpowiedź (wolny przebieg)
    • odebranie odpowiedzi (download zatkany)

    jakiś inny proces będzie mógł wysyłać swój komunikat podczas, gdy ten pierwszy czeka lub odbiera odpowiedź. Ale nie masz gwarancji, że 10 procesów da Ci automatycznie 10 razy szybsze wykonanie - musisz przeprowadzić testy. Ponadto będziesz mógł odebrać odpowiedź na dowolny komunikat, którego przetwarzanie już się zakończyło, niezależnie od Twojej pętli, i konsumować już gotowe wyniki. Upłynni Ci to wykonanie nawet, jeśli przyspieszenie będzie niewielkie.

Sprawdź wszystkie możliwości, zamiast powtarzać, że nie chcesz czegoś robić. Chcesz przyspieszyć program - skup się na likwidacji wąskich gardeł. Nie chcesz pokazać kodu i jesteś oszczędny w opisie tego, co się dzieje pod spodem - spoko, ale jeśli nie będziemy nic wiedzieć, a Ty nie spróbujesz wypróbować naszych podpowiedzi, to nie będziemy w stanie Ci pomóc, a tylko zrazisz do siebie ludzi i następnym razem przeczytasz radź sobie sam, przecież nie chciałeś pomocy.


Blocker wiszący od miesiąca? Mówisz o tym criticalu z zeszłego tygodnia? A, tak, zalogowaliśmy przedwczoraj tego minor buga. Pewnie, zajmę się ASAP tym enhancementem. Nie ma sprawy, jak tylko podomykam taski to wezmę się za ten ficzer, tylko go jeszcze wyestymujemy przed kolejnym sprintem.
Podpisuje się rękami i nogami. Osobiście śledzę wątek bo każde 'przyspieszanie' kodu to dla mnie temat-rozrywka. Ale 'tajemnice pentagonu' w świecie pythona (Open-source) to kompletna bzdura, zwłaszcza gdy chcesz aby ktoś ci pomógł :D. - Guaz 2019-02-10 19:11

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0