Translate: 
EnglishFrenchGermanItalianPolishPortugueseRussianSpanish

Jak przyspieszyć kompilację kodu PHP w HipHop for PHP – część I: ccache

Kompilacja dowolnego programu napisanego w języku PHP zależnie od jego rozmiaru może trwać od kilku do kilkudziesięciu minut.

Dla programistów C, C++ i Java długotrwała kompilacja kodu nie jest niczym niezwykłym. Niestety nie można tego samego powiedzieć o programistach PHP, którzy przywykli do tego, że wszystkie zmiany w kodzie widzą od razu w przeglądarce.

W artykule przedstawię więc jeden ze sposobów, który znacząco skraca czas kompilacji kodu PHP.

Teoria

W przypadku translatora HipHop for PHP zmiana chociażby jednej linijki kodu PHP niesie ze sobą konieczność ponownego skompilowania aplikacji oraz jej wszystkich kodów źródłowych.

Aby temu zaradzić wystarczy posłużyć się programem ccache. Przechwytuje on pliki wynikowe kompilatora gcc, używając ich podczas kolejnych kompilacji kodu jeśli ich kody źródłowe nie uległy do tego czasu modyfikacjom.
W razie wykrycia zmian w kodzie PHP, ccache wymusza na kompilatorze ponowne skompilowanie wyłącznie tych plików, które zostały zmienione po ostatniej kompilacji.

Platforma testowa

Procesor: Intel(R) Core(TM)2 Duo CPU E7600 @ 3.06GHz
Pamięć: 2,5GB RAM
System: Fedora 12 (64bit)
Kernel: 2.6.32.26-175.fc12.x86_64 #1 SMP

Maszyna była wykorzystywana wyłącznie do kompilacji kodu.

Uwagi wstępne

W tym artykule przedstawię sposób instalacji ccache na podstawie systemu Fedora. Wykonanie poniższych kroków na innej dystrybucji Linuxa nie powinno jednak nastręczać żadnych trudności. Użyte moduły są łatwo dostępne w pozostałych systemach operacyjnych.

Instalacja ccache

Program ccache można w prosty sposób zainstalować w systemie Fedora następującym poleceniem:

yum -y install ccache

Po pomyślnym zakończeniu instalacji, konieczne jest jeszcze wskazanie narzędziu make, by od tej chwili korzystało z cache kompilatora. W tym celu wystarczy nadpisać dwie zmienne środowiskowe:

export CC="ccache gcc"
export CXX="ccache g++"

Dla szybszej kompilacji skryptów PHP warto także włączyć równoległą kompilację plików. Służy do tego przełącznik -jX, gdzie X to ilość równoległych procesów gcc pracujących na kodach źródłowych. Wartość ta powinna być równa ilości jednostek CPU dostępnych na serwerze, na którym przebiega kompilacja.

Oto przykładowe ustawienie, włączające 3 równoległe procesy kompilatora:

export MAKEOPTS=' -j3 '

Podczas ustawiania tego parametru należy pamiętać o tym, że zbyt duża ilość procesów kompilatora może zająć całą pamięć RAM i w efekcie spowolnić kompilację programu.

Test wydajności

Jako aplikację do skompilowania ccache wykorzystałem system Drupal 7. Jest to bardzo rozbudowana aplikacja, której kod źródłowy znajduje się w 596 plikach PHP.

Do kompilacji systemu Drupal posłużyłem się poniższym poleceniem:

cd drupal
~/hiphop/hiphop-php/src/hphp/hphp \
 --keep-tempdir=1\
 --log=3\
 --input-list=files.full.list\
 --include-path="."\
 --force=1\
 --cluster-count=120\
 -v "AllDynamic=true"\
 -v "AllVolatile=true"\
 -o /tmp/drupal\
 --parse-on-demand 0

W powyższym poleceniu nie trzeba ustawiać żadnych parametrów dotyczących ccache, ponieważ narzędzie to jest uruchamiane automatycznie (dzięki wyeksportowanym wcześniej zmiennym środowiskowym CC i CXX).

Jako wynik referencyjny posłuży pierwsza kompilacja bez wykorzystania narzędzia ccache:

[...]
compiling and linking CPP files took 14'47" (887611 ms) (null)
all files saved in /tmp/drupal ...
running hphp took 14'59" (899128 ms) (null)

W ramach porównania przedstawiam też wynik pierwszej kompilacji z wykorzystaniem ccache:

compiling and linking CPP files took 14'22" (862060 ms) (null)
all files saved in /tmp/drupal ...
running hphp took 14'33" (873759 ms) (null)

Jak widać skompilowanie całego systemu Drupal zajęło w obu przypadkach ponad 14 minut.

Dla testów dodałem więc jedną linijkę kodu do pliku includes/install.core.inc zgłaszającą błąd typu E_NOTICE przy pomocy funkcji trigger_error().

Następnie ponownie skompilowałem projekt otrzymując poniższy wynik:

[...]
compiling and linking CPP files took 1'19" (79849 ms) (null)
all files saved in /tmp/drupal ...
running hphp took 1'31" (91438 ms) (null)

Tym razem czas oczekiwania był o wiele krótszy, dzięki narzędziu ccache zmodyfikowany system Drupal został skompilowany w niecałe dwie minuty.

Ostatnim testem jest sprawdzenie, ile trwa ponowne skompilowanie kodu, który nie został w ogóle zmodyfikowany po ostatniej kompilacji.

Wynik ostatniej kompilacji wygląda następująco:

[...]
compiling and linking CPP files took 1'11" (71654 ms) (null)
all files saved in /tmp/drupal ...
running hphp took 1'23" (83436 ms) (null)

Podsumowanie

Poniżej przedstawiam podsumowanie wyników:

Tryb kompilacji Czas [ms] Czas [%]
Tradycyjna 887611 100,00%
Pierwsza (ccache) 873759 98,43%
Kolejna po zmianach kodu (ccache) 91438 10,30%
Kolejna bez zmian kodu (ccache) 83436 9,40%

HipHop for PHP & ccache

Przeprowadzone testy pokazują wyraźnie korzyści, jakie płyną z używania ccache do kompilowania plików PHP. Narzędzie to jest bardzo pomocne przy małych ale częstych zmianach w kodzie, przyspieszając proces kompilacji nawet dziesięciokrotnie.

Opisany mechanizm nie wpływa niestety na czas pierwszej kompilacji. W kolejnym artykule z tej serii zademonstruję więc, jak jeszcze bardziej przyspieszyć ten proces za pomocą kompilowania rozproszonego.

Tagi: , ,

Dodaj odpowiedź