Wpis z mikrobloga

#programowanie #php #dev

No dobra, dzisiaj muszę pobrać ze dane ze strony. Uzywam #symfony2 i #goutte
Mam już wszystko gotowe, skrypt działa i w ogóle. Problem jest taki że strona ma ogromną ilość podstron.
Np

Lista elementów:
|- Lista obiektów:
|- spis
|- spis
|- spis
|- Lista obiektów:
|- spis
|- spis
|- spis
|- Lista obiektów:
|- spis
|- spis
|- spis

więc wychodzi tego naprawdę dużo. Problem mam taki że na początku skrypt w miarę fajnie leci, i ETA wychodzi około 2h. Ale po 20 minuach wzrazta już do 3h a po kolejnych do 7 i tak dalej..

Zrobiłem taki myk:

$em = $this->getContainer()->get('doctrine')->getEntityManager();
$em->getConnection()->getConfiguration()->setSQLLogger(null);

Ale niewiele to dało... Przez przeglądarkę strona mi się odpala od strzału, nie ma żadnej zadyszki ani nic... tylko skrypt zwalnia..
Na końcu pętli mam persisty i flush
Co jeszcze mogę zrobić?
Dodam że skrypt jest napisany w #symfony2 pod konsolą (command).
  • 16
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@qwelukasz: Generalnie powinieneś pakować to w paczki (po powiedzmy 50 obiektów jeśli jeszcze tego nie robisz), a po flushu warto przeiterować po tych obiektach i zrobić na nich

$entityManager->detach($object);
Wtedy Garbage Collector będzie mógł od razu je zgarnąć i posprzątać, w innym przypadku siedzą w pamięci niepotrzebne obiekty.

edit: ewentualnie po flushu zrób $em->clear(); który detachuje wszystkie obiekty w EM
  • Odpowiedz
@qwelukasz: robić flusha i clear co 50 iterację, kodu nie chce mi się pisać w tym momencie, więc musisz sam sobie poradzić, co do opcache musisz go włączyć w konfiguracji PHP, a nie apki. Env prod na końcu w takiej postaci jak Ci napisałem
  • Odpowiedz
@qwelukasz: na devie system zbiera bardzo dużo informacji przydatnych do debugowania i za każdym razem przeładowuje konfiguracje, której nie cachuje. Zrób również php app/console cache:warmup --env=prod przed wykonaniem komendy. Znacznie przyspiesza całość aplikacji.
  • Odpowiedz
@qwelukasz: Tak się tego nie robi, uruchom sobie skrypt równolegle i zobacz jak zmienia się ETA. Jeżeli rozdzielisz to na osobne zadania razem z jakaś kolejka, to pozbędziesz się obecnych problemów a dodatkowo przyspieszysz pobieranie treści.
  • Odpowiedz
@qwelukasz:

Poniżej masz kawałek przykładowego kodziku w jaki sposób możesz uniknąć ładowania danych do arraya i iterowania później po tym. Tablice w PHP zjadają bardzo dużo pamięci, dopiero w PHP 7 będzie to znacznie zoptymalizowane. Ciężko mi się wypowiedzieć bo nie widzę tego co masz napisane. W każdym razie powyciągane (nie wiem skąd) obiekty ładujesz sobie do kolekcji, a jak już masz wszystko to robisz sobie

foreach($objectCollection->getIterator() as
  • Odpowiedz
@qwelukasz: Nie bardzo łapię o co teraz ci chodzi. Masz problem z wydajnością skryptu. Z pewnością w PHP iterowanie po dużych arrayach nie należy do najwydajniejszych dlatego przedstawiłem ci szybszą opjcę z wykorzystaniem SplObjectStorage i generatora dostępnego od PHP 5.5. Popisz sobie różne opcje i sam wyciągaj wnioski, w googlach też sporo na ten temat znajdziesz. Tutaj się raczej nie dogadamy.
  • Odpowiedz
@hajs86: hmm, no o może inaczej.
Jeżeli mam kolekcję. Jak mogę z niej pobrać konkretny obiekt z pominięciem foreach?
Załóżmy że mam obiekt Miasto oraz obiekt NazwaMiasta

Obiekt Miasto posiada ID z NazwaMiasta.
W przypadku tablic zrobiłbym
  • Odpowiedz