Artur Świerc

Artur Świerc Programista PHP/Java

Temat: przetwarzanie bardzo dużej ilości danych

Witam,

szukam jakichś miarodajnych statystyk, lub też informacji z waszych obserwacji co do wydajności pythona w przetwarzaniu bardzo dużej ilości wyników z bazy. W php albo brakuje pamięci, albo czasu :)

W pythonie przetwarzałem kiedyś bardzo duże pliki z którymi php sobie nie radził i chciałbym mieć pewność że język ten i tym razem mnie nie zawiedzie.

Pozdr.
Piotr Maliński

Piotr Maliński Programista
Python/Django

Temat: przetwarzanie bardzo dużej ilości danych

W PHP wystarczy np. odpalić z konsoli z bardzo wysokim maksymalnym czasem wykonywania - najprościej dla niego. W Pythonie podobnie - jak chcesz coś dużo przetwarzać to nie widokiem webowym, tylko skryptem konsolowym, co może sobie powisieć na maszynie trochę. No i w obu językach jeżeli wczytasz cały plik na raz to rozmiar zajętej pamięci powiększy się o rozmiar pliku.

konto usunięte

Temat: przetwarzanie bardzo dużej ilości danych

pehapa nawet nie z CL mozna odpalic z zerowym time limitem. do tego chociazby cyclic buffer w przypadku plikow (sam uzywam do parsowania jebitnych logów) i rozsadne zapytania w przypadku DB i nie ma zadnych problemowMateusz Jaworski edytował(a) ten post dnia 18.09.10 o godzinie 23:21

konto usunięte

Temat: przetwarzanie bardzo dużej ilości danych

Artur Świerc:
W pythonie przetwarzałem kiedyś bardzo duże pliki z którymi php sobie nie radził i chciałbym mieć pewność że język ten i tym razem mnie nie zawiedzie.

Pozdr.

Jeżeli ręce nie są krzywe, to problemów nie powinno być. Jeżeli natomiast robisz wszystko, by pythonowski śmieciarz nie mógł ci sprzątnąć niepotrzebne obiekty (np. trzymając gdzieś wskaźniki „na wszelki wypadek” lub co innego w tym rodzaju), a potem brakuje ci pamięci, to niestety nie będzie tu pomocny żadny język. Jeżeli jednak nie, to chyba musi zadziałać.

To samo można powiedzieć o każdym języku oprócz chyba PHP, u którego pamięć przecieka jak zardzewiała radziecka rura, bo jego realizacja jest sama w sobie na tyle dziurawa, że nawet najbardziej kwalifikowany programista nic na to nie poradzi ze strony skryptu.

konto usunięte

Temat: przetwarzanie bardzo dużej ilości danych

Artur Świerc:
Witam,

szukam jakichś miarodajnych statystyk, lub też informacji z waszych obserwacji co do wydajności pythona w przetwarzaniu bardzo dużej ilości wyników z bazy. W php albo brakuje pamięci, albo czasu :)

Nie wiem jak w WWW, ale przy "bardzo dużej ilości wyników z bazy" zwykle na mainframe robi się:
- zrzut zapytania do pliku (narzędziem producenta DBMS-a)
- ew. sortowanie i filtrowanie pliku
- przetworzenie plik A -> plik B (programem)
- wrzucenie wyniku do bazy "batch loadem" (narzędziem DBMS-a)

To prostackie, ale dzięki temu:
- baza nie jest blokowana przy długim przetwarzaniu
- proces jest bardzo krotki

Wada: ostatni krok - w stosunku do procesu czysto-SQL-owego - jest mniej kontrolowalny - w przypadku błędów.

Można też się posiłkować tabelą tymczasową - tam zrzucić wynik i na niej operować. Dzięki temu rekordy źródłowe nie są blokowane.

A co do wycieków - to przy dużej ilości danych trzeba być przygotowanym na to, że jeśli proces trwa np. 8h to wzrasta szansa na to że się wywali na końcu (wyciek pamięci, awaria sieci, neutrino...). A więc warto go podzielić na etapy, tak, żeby w wypadku awarii móc powtórzyć tylko np. ostatnią godzinę (work unit, commit, restartowalność) - lub mniej.
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: przetwarzanie bardzo dużej ilości danych

Oczywiście że chodzi mi o CLI.

Trzeba przeliczyć bardzo duża liczbę rekordów. Pamiętam, że gdy potrzebowałem przetworzyć ciężkie pliki to php co chwilę się wysypywał z racji braku pamięci - nawet gdybym na serwerze miał 20gb przydzielone to pewnie dla niego byłoby za mało ;)

Szukałem pewnych statystyk czy też porównań szybkości dla tych dwóch języków, biorąc pod uwagę, że robimy także operacje na bazie - selecty/joiny, foreacha z updatem na większą skalę. Dlatego też założylem ten wątek - chciałem się upewnić, że python mnie w tym przypadku nie zawiedzie, nie wysypie się w połowie pracy i że takie operacje wykona szybciej niż php.

Zastanawialiśmy się też nad przeniesieniem całości do bazy - tzn napisać procedurę, która by była odpalana z jakiegoś bash'a. Byłoby to chyba najlepsze i najszybsze rozwiązanie.Artur Świerc edytował(a) ten post dnia 19.09.10 o godzinie 17:21
Stanisław P.

Stanisław P. Software designer

Temat: przetwarzanie bardzo dużej ilości danych

Artur Świerc:
Szukałem pewnych statystyk czy też porównań szybkości dla tych dwóch języków, biorąc pod uwagę, że robimy także operacje na bazie - selecty/joiny, foreacha z updatem na większą skalę. Dlatego też założylem ten wątek - chciałem się upewnić, że python mnie w tym przypadku nie zawiedzie, nie wysypie się w połowie pracy i że takie operacje wykona szybciej niż php.
Jeśli te operacje to w większości baza danych, to raczej język będzie miał mały wpływ :(

A benchmark - najlepiej własny. Po prostu przepisz ten kawałek który robi najwięcej pracy poza bazą i sam sprawdź jak wypada porównanie.
Wojciech Soczyński

Wojciech Soczyński Programista
eksplorator -
blog.wsoczynski.pl

Temat: przetwarzanie bardzo dużej ilości danych

Moim zdaniem, czy to w pythonie czy w php, takie przetwarzanie należało by podzielić na kilka osobnych kroków, podobnie jak to opisał Piotr L. .Nie ma doskonałego GC, a zamknięcie skryptu i kontynuacja przetwarzania w następnym zawsze wyczyści pamięć, chociaż całość może działać troszkę wolniej.
Adam Mańczuk

Adam Mańczuk programista, artysta
informatyk

Temat: przetwarzanie bardzo dużej ilości danych

miałem do czynienia z tego typu zadaniami
należy ostrożnie dobrać typ kursora, sprawdź sobie dokumentację na temat dostępnych klas kursora
z dobrze dobranym kursorem python jest w stanie przetwarzać nawet iloczyny kartezjańskie gigabajtowych tabel
pozdrawiam
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: przetwarzanie bardzo dużej ilości danych

Adam Mańczuk:
miałem do czynienia z tego typu zadaniami
należy ostrożnie dobrać typ kursora, sprawdź sobie dokumentację na temat dostępnych klas kursora
z dobrze dobranym kursorem python jest w stanie przetwarzać nawet iloczyny kartezjańskie gigabajtowych tabel
pozdrawiam

Adamie, czy wspominając o kursorach masz na myśli jakieś DbApi tak jak w phpie pdo, mysqli itp?
Czy mógłbyś jakiś polecić?
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: przetwarzanie bardzo dużej ilości danych

btw: napisałem dwa proste skrypty, oba odpalane z linii polecen. Ku mojemu zdziwieniu pythonowski wykonał się wolniej. Nie wiem jednak jak z użyciem pamięci. Wiem jednak, że w pythonie nigdy nie miałem problemu z brakiem pamięci czy też czasu ;)

php:

$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'root';
$password = '';

$db = new PDO($dsn, $user, $password);

$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
$db->exec("insert into test_insert (iter) values (" . $i . ")");
}
$stop = microtime(true);

$total = $stop - $start;
echo "czas: " . $total;


python:

import MySQLdb
import time

db = MySQLdb.connect(host="localhost", user='root', passwd='', db="test", charset='utf8')
c = db.cursor();

t = time.time()
for i in range(0, 1000000):
c.execute("insert into test_insert (iter) values (%s)" % i)

print 'czas %.02f' % (time.time() - t)



php: 227.795 s.
python: 297.09 s.
Stanisław P.

Stanisław P. Software designer

Temat: przetwarzanie bardzo dużej ilości danych

Niestety te skrypty są trochę dziwne. Nie wypowiem się za dużo o wersji phpowej, ale:

1. Jak wykonujesz cały czas to samo zapytanie, to rób to przez prepared statements.
2. Jeśli wykonujesz te same inserty w jednym miejscu, to rób to poprzez `.executemany()`.
3. Jeśli masz dużo insertów, to zwiń je po ~20 (czy jakie inne sobie znajdziesz miejsce optymalne) w jedno zapytanie.
4. Jeśli dodajesz hurtem, poza tranzakcją i nie musisz od razu czytać wyników, to zmień `INSERT` na `INSERT DELAYED`.
5. Jeśli robisz benchmarki czegoś na czym Ci zależy, to rób to porządnie - polecam http://docs.python.org/library/timeit.html - albo własną wersję która liczy min, max, średnią i odchylenia, bo inaczej tak naprawdę nie wiesz czy jedno zapytanie czekało 100 sekund, a reszta się wykonała w 197, czy miałeś standardowy rozkład.
6. Shedskin, psyco, unleaden swallow, etc...

Wyniki które wkleiłeś niestety niczego praktycznie nie dowodzą.Stanisław Pitucha edytował(a) ten post dnia 21.09.10 o godzinie 21:09
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: przetwarzanie bardzo dużej ilości danych

skrypciki są szybkie (szybko napisane) i proste. Chciałem uzyskać ogólny obraz co do szybkości operacji z bardzo wieloma wynikami.
Wielkie dzięki za rady! W normalnym skrypcie przeliczającym na pewno zastosujemy różne techniki optymalizacyjne :)Artur Świerc edytował(a) ten post dnia 21.09.10 o godzinie 21:15
Łukasz Dudek

Łukasz Dudek Database
Administrator

Temat: przetwarzanie bardzo dużej ilości danych

po pierwsze named cursor
po drugie fetchmany

jeśli baza łyka tak duży set to sobie już z tym poradzisz.

konto usunięte

Temat: przetwarzanie bardzo dużej ilości danych

Artur Świerc:
btw: napisałem dwa proste skrypty, oba odpalane z linii polecen. Ku mojemu zdziwieniu pythonowski wykonał się wolniej. Nie wiem jednak jak z użyciem pamięci. Wiem jednak, że w pythonie nigdy nie miałem problemu z brakiem pamięci czy też czasu ;)
php: 227.795 s.
python: 297.09 s.

A za jaki czas wykona się taki oto skrypcik?


import MySQLdb
import time, math

db = MySQLdb.connect(host="localhost", user='root', passwd='',
db="test", charset='utf8')
db.autocommit(False)
c = db.cursor();

at_a_time = 50
total_records = 1000000

t = time.time()
remaining = total_records
for i in range(0, int(math.ceil(total_records * 1.0 / at_a_time))):
rsize = min(at_a_time, remaining)
ipart = ", ".join(["(%s)"] * rsize)
records = list(xrange(i * at_a_time, (i+1) * at_a_time - (at_a_time - rsize)))
c.execute(("insert into test_insert (iter) values " + ipart), records)
remaining -= rsize

c.commit()

print 'czas %.02f' % (time.time() - t)


U mnie jest od 10 do 15 razy szybciej od Twojego, zależnie od zmiennej at_a_time...
Łukasz Dudek

Łukasz Dudek Database
Administrator

Temat: przetwarzanie bardzo dużej ilości danych

Jarosław Fedewicz:
Artur Świerc:
btw: napisałem dwa proste skrypty, oba odpalane z linii polecen. Ku mojemu zdziwieniu pythonowski wykonał się wolniej. Nie wiem jednak jak z użyciem pamięci. Wiem jednak, że w pythonie nigdy nie miałem problemu z brakiem pamięci czy też czasu ;)

php: 227.795 s.
python: 297.09 s.

A za jaki czas wykona się taki oto skrypcik?
>
U mnie jest od 10 do 15 razy szybciej od Twojego, zależnie od zmiennej at_a_time...

robisz wiele insertów na raz i wyłaczyłeś autocommit ... zawsze jest to szybciej (tak działaja bazy)
po za tym po co tak kombinować ? nie lepiej uzyc executemany (prostszy kod) i użyć argumntacji a nie sklejania stringów.
Jak jeszcze chcesz przyspieszyc to jest prepare oraz xrange .Łukasz Dudek edytował(a) ten post dnia 27.09.10 o godzinie 20:34

konto usunięte

Temat: przetwarzanie bardzo dużej ilości danych

Łukasz Dudek:
po za tym po co tak kombinować ? nie lepiej uzyc executemany (prostszy kod) i użyć argumntacji a nie sklejania stringów.

Jeżeli czytałeś uważnie, to sklejają się "%s", a nie faktyczne wartości.

No i poza tym, po prostu zilustrowałem rzeczy oczywiste, to przecież nie jest kod productionowy, lecz tak, hint, w którą to stronę kopać.
Łukasz Dudek

Łukasz Dudek Database
Administrator

Temat: przetwarzanie bardzo dużej ilości danych

Jarosław Fedewicz:
Łukasz Dudek:
po za tym po co tak kombinować ? nie lepiej uzyc executemany (prostszy kod) i użyć argumntacji a nie sklejania stringów.

Jeżeli czytałeś uważnie, to sklejają się "%s", a nie faktyczne wartości.
faktycznie ... tylko po co?

No i poza tym, po prostu zilustrowałem rzeczy oczywiste, to przecież nie jest kod productionowy, lecz tak, hint, w którą to stronę kopać.
pisz tak kod abyś nie wstydził się użyć tego produkcyjnie.
prościej i czytelniej.

total_records = 1000
step = 50
for x in xrange(0,total_records,step):
rec = [ (a,) for a in xrange(x,x+step)]
cursor.executemany("""insert into test_insert (iter) values (%s)""",rec)

+ ewntualna obsługa skrajnego step'a który się nie mieści
Bartłomiej Ogryczak

Bartłomiej Ogryczak Backend Developer @
Layar

Temat: przetwarzanie bardzo dużej ilości danych

Artur Świerc:
Witam,

szukam jakichś miarodajnych statystyk, lub też informacji z waszych obserwacji co do wydajności pythona w przetwarzaniu bardzo dużej ilości wyników z bazy. W php albo brakuje pamięci, albo czasu :)

PHP wyjątkowo nieefektywnie trzyma dane w pamięci. Trzyma je jako ZVAL, które jest *tekstową* reprezentacją wartości (to nie żart).

W przypadku Pythona dosyć istotne może być dostosowanie parametrów GC do własnych potrzeb.



Wyślij zaproszenie do