Niepotrzebne wywołania funkcji w PHP – optymalizacja kodu

Ten artykuł to kolejna część optymalizacji kodu PHP – czyli szukamy cennych milisekund niepotrzebnie marnowanych w naszych skryptach PHP ;-)
Niepotrzebne wywołania funkcji w PHP, to przeważnie nieświadomie stworzone błędne konstrukcje, które opóźniają nasze skrypty. Należy pamiętać, iż każde wywołanie funkcji w PHP to dodatkowe obciążenie dla procesora i pamięci. Jeśli wynik działania funkcji używany jest w wielu miejscach, najlepiej jest go zapamiętać (podstawić pod zmienną) – i dalej operować na zmiennej, niż wywoływać tę samą funkcję z tymi samymi argumentami.

Klasycznym przykładem jest wywołanie funkcji for.
Np: for($i=0;$i<count($tab);$i++) { … };
Należy zauważyć, iż funkcja zliczająca ilość elementów tablicy count() wywoływana jest za każdym razem przebiegu pętli for.
Zamiast tego wynik działania tej funkcji można zapisać do zmiennej tymczasowej, a w warunku porównywać zmienną zamiast wartości funkcji.

Funkcja testująca:
<?php
function microtime_float() {
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}
$tab = array();
for($i=0;$i<1000000;$i++) $tab[] = $i;

$czas1 = microtime_float();
// Sposob 1: funkcja for – wywołująca za każdym razem funkcję count()
// for($i=0;$i<count($tab);$i++) $temp = $tab[$i];
// Sposob 2: funkcja for – funkcja count() wywołana tylko raz
// for($i=0,$c=count($tab);$i<$c;$i++) $temp = $tab[$i];
$czas2 = microtime_float();
echo round($czas2-$czas1,6);
?>

Jak widać test polega na prostej iteracji do miliona razy. W pierwszym przypadku funkcja for wywołuje za każdym razem funkcję count(), w drugim przypadku wartość funkcji count() została zapisana pod zmienną $c – w części inicjalizującej zmienne.

Wyniki testowania:
<pre>
Test nr.1: 1,389940, Test nr.2: 0,996266
Test nr.1: 1,355410, Test nr.2: 0,999128
Test nr.1: 1,382061, Test nr.2: 0,969845
Średnia 1: 1,375804, Średnia 2: 0,988413
</pre>

Wnioski:
Wniosek jest prosty, zamiast wywoływać kilka razy tę samą funkcję, lepiej skorzystaj ze zmiennej tymczasowej. Zaoszczędzisz czas i “pieniądze”.

Posted in Optymalizacja, PHP | Tagged , , , , | Leave a comment

Optymalizacja łączenia zmiennych w PHP. Podwójny cudzysłów czy apostrof | Optymalizacja PHP

Zainspirowany pewnym artykułem dotyczącym optymalizacji cytowania stringów – podczas wyświetlania lub łączenia zmiennych postanowiłem zrobić własny test.
W PHP do cytowania stringów można użyć znaku apostrofa lub cudzysłowu, dodatkowo zmienne zapisane w podwójnym cudzysłowu można zapisać w nawiasach klamrowych. Który sposób jest bardziej wydajny – poniżej wyniki testu.

Sposoby cytowania tekstu – przypisywania zmiennych:
// Sposób 1: tekst łączony za pomocą apostrofa – zewnętrznie
$x = $a.’ ‘.$b.’ ‘.$c;
// Sposób 2: tekst łączony za pomocą cudzysłowu – zewnętrznie
$x = $a.” “.$b.” “.$c;
// Sposób 3: tekst łączony za pomocą cudzysłowu – wewnętrznie
$x = “$a $b $c”;
// Sposób 4: tekst łączony za pomocą cudzysłowu – wewnętrznie, zmienne w nawiasach klamrowych
$x = “${a} ${b} ${c}”;

Skrypt testujący:
<?php
function microtime_float() {
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}
$czas1 = microtime_float();
for($a=0;$a<100;$a++)
for($b=0;$b<100;$b++)
for($c=0;$c<100;$c++)
// wstawić wybrany sposób;
$czas2 = microtime_float();
echo round($czas2-$czas1,6);
?>

Jak widać test polega na prostej iteracji trzech zmiennych i przypisaniu ich do jednej zmiennej. Każda sposób jest przetestowany za pomocą miliona podstawień (100x100x100).

Wyniki testowania:
<pre>
Test nr.1: 1,017789, Test nr.2: 0,971977, Test nr.3: 0,891271, Test nr.4: 0,868639
Test nr.1: 1,004230, Test nr.2: 0,987173, Test nr.3: 0,905349, Test nr.4: 0,895470
Test nr.1: 1,006419, Test nr.2: 0,997731, Test nr.3: 0,892430, Test nr.4: 0,870490
Średnia 1: 1,009479, Średnia 2: 0,985627, Średnia 3: 0,896350, Średnia 4: 0,878200
</pre>

Wnioski:
Wyniki testu dotyczą miliona podstawień – zatem różnica kilku milisekund w poszczególnych testach to bardzo niewiele jeżeli chodzi o optymalizację skryptów PHP.
Jednak mimo wszystko można zauważyć, iż cytowanie stringów (przepisywanie zmiennych) za pomocą podwujnego cudzysłowu jest trochę szybsze od apostrofa.
Dodatkowo cytowanie za pomocą podwójnego cudzysłowu realizowane wewnętrzne jest szybsze od łączenia zewnętrznego.
Najlepszym i najszybszym sposobem jest cytowanie w podwójnych cudzysłowach ze zmiennymi ujętymi w nawiasy klamrowe – realizowane przez łączenie wewnętrzne.
Wyniki testu są tym bardziej zaskakujące, iż na wielu serwisach dotyczących optymalizacji wnioski były odwrotne.
Ciekawe z czego to wynika… (ze sprzętu, wersji PHP, …)?

Posted in Optymalizacja, PHP | Tagged , , , , , , , | Leave a comment

Wydajność funkcji echo w PHP. Echo vs Podstawienie pod zmienną – testy.

Zastanawialiście się kiedyś ile milisekund, lub nawet sekund można stracić używając funkcji echo. Oczywiście strata dotyczy tylko przypadku w którym funkcja echo jest wywoływana kilkanaście razy, zamiast np. tekst podstawić pod jedną zmienną i tylko raz wywołać funkcję echo.

Proste przykłady z życia programisty PHP – na wyświetlenie tabelki:
Przykład nr 1.
<?php
echo ‘<table>’;
echo ‘<tr>’;
echo ‘<td></td>’;
echo ‘<td></td>’;
echo ‘</tr>’;
echo ‘</table>’;
?>

Przykład nr 2.
<?php
$tabelka = ‘
<table>
<tr>
<td></td>
<td></td>
</tr>
</table>
‘;
echo $tabelka;
?>

Przykład nr 3.
<?php
echo ‘
<table>
<tr>
<td></td>
<td></td>
</tr>
</table>
‘;
?>

Który sposób jest najlepszy, a który najgorszy?

Schemat testowania .
Testowanie odbyło się z linii poleceń PHP. Poniżej przedstawiam kod testowania funkcji. Pierwszy sposób to wielokrotne podstawienie pod zmienną i wyświetlenie po zakończeniu iteracji, drugi sposób to wielokrotne wyświetlenie. Dla pewności, skrypt został uruchomiony 3 razy dla każdego sposobu.

Kod testowania funkcji:
<?php
function microtime_float() {
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}
$x = ”;
$czas1 = microtime_float();
// Sposób nr 1: Wielokrotne podstawienie pod zmienną, jedno wyświetlenie
// for($i=0;$i<100000;$i++) $x .= $i; echo $x;
// Sposób nr 2: Wielokrotne wyświetlenie zmiennej, bez podstawiania
// for($i=0;$i<100000;$i++) echo $i;
$czas2 = microtime_float();
$czas0 = round($czas2-$czas1,6);
?>

Wyniki testowania:
<pre>
Test nr. 1: 1,124184  Test nr. 2: 11,096614
Test nr. 1: 1,125416  Test nr. 2: 11,200453
Test nr. 1: 1,122321  Test nr. 2: 11,202271
Średnia: 1: 1,123973, Średnia: 2: 11,166446
</pre>

Wnioski:
Sposób nr. 1 i sposób nr. 2 doprowadzi nas do tego samego wyniku (zostanie wyświetlony ciąg licz od 0 do 10 tys.), jednak wyniki testu są oczywiste.
Podstawianie w języku PHP jest bardzo zoptymalizowane.
Np. instrukcja typu: for($i=0;$i<1000000;$i++) $x .= $i; – zostanie wykonana w zaledwie 0,5 sek. (pół sekundy i milion podstawień tworzący ciąg tekstowy).
Funkcja echo – służąca do wyświetlania zmiennych tekstu na standardowe wyjście, też jest mocno zoptymalizowana, jednak częste używanie funkcji spowalnia skrypty.
Lepiej podstawić ciąg tekstowy pod jedną zmienną, którą na samym końcu wyświetlimy jednym wywołaniem: echo $zmienna;

Podsumowanie:
1. Każda operacja w PHP zużywa czas.
2. Operacja podstawienia (np. $zmienna = ‘wartość’) jest bardzo zoptymalizowana.
3. Operacja wywołania echo jest zoptymalizowana, jednak często wywoływana jest wolniejsza od podstawienia pod jedną zmienną i wyświetlenia tej zmiennej.
Wniosek: Więcej podstawień, mniej wywołań echo, to lepsza optymalizacja i szybszy kod PHP.

Teraz już wiecie który przykład z wyświetleniem tabelki jest najszybszy!
Oczywiście przykład nr.1 – jest najgorszy – funkcja echo jest niepotrzebnie wywoływana 6 razy, natomiast przykład nr.3 – jest najlepszy – jedno wywołanie funkcji echo.

Posted in Optymalizacja, PHP | Tagged , , , , , , , , , | Leave a comment

Wydajność funkcji echo w PHP. Sposób optymalizacji – testy.

Funkcja echo w PHP – nie ma kogoś, kto posługując się językiem PHP, nie używałby tej funkcji. Funkcja prosta i łatwa w obsłudze, z możliwością użycia na kilka różnych sposobów. Echo to tak naprawdę składnia języka PHP (ale, jak zwał tak zwał ;-). Dzisiaj przetestujemy, który sposób użycia funkcji echo jest najbardziej wydajny. Chociaż mając na uwadze to, iż echo należy do składni języka – z góry można założyć, iż funkcja sama w sobie jest mocno zoptymalizowana.

Funkcja echo używana jest do wyświetlania (tekstu, zmiennych, wyników) na standardowe wyjście (konsola, strona www).
Sposoby użycia funkcji echo w języku PHP:

$zmienna = ‘Zawartość mojej zmiennej w PHP’;

// sposób nr. 1
echo $zmienna.’ testowany tekst’;
// sposób nr. 2
echo $zmienna.” testowany tekst”;
// sposób nr. 3
echo “$zmienna testowany tekst”;
// sposób nr. 4
echo $zmienna; echo ‘ testowany tekst’;
// sposób nr. 5
echo “${zmienna} testowany tekst”;
// sposób nr. 6
echo ‘Zawartość mojej zmiennej w PHP. testowany tekst’;

Schemat testowania funkcji echo.
Funkcja echo została przetestowana z linii poleceń PHP. Poniżej przedstawiam kod testowania funkcji. Jest to nic innego jak iteracja (do 10 tys. razy) i wyświetlenie tekstu za pomocą kolejnych sposobów. Za każdy razem zostaje zmierzony czas wykonania całości iteracji. Dla pewności skrypt został uruchomiony 5 razy dla każdego sposobu.

Kod testowania funkcji echo:
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$zmienna = 'Zawartosc mojej zmiennej w PHP.';

$czas1 = microtime_float();
for($i=0;$i<10000;$i++) {
// sposob nr. x
}
$czas2 = microtime_float();
echo round($czas2-$czas1,6);
?>

Wyniki testowania funkcji echo:

Test nr. 1: 1:3,201627  2:3,195476  3:3,196249  4:4,085179  5:3,169852  6:3,293718
Test nr. 2: 1:3,130458  2:3,263948  3:3,207585  4:3,835533  5:3,168425  6:3,262281
Test nr. 3: 1:3,075266  2:3,164228  3:3,128738  4:4,173969  5:3,113928  6:3,267293
Test nr. 4: 1:3,121783  2:3,331647  3:3,373735  4:3,921561  5:3,273135  6:3,319214
Test nr. 5: 1:3,874715  2:3,355851  3:3,469895  4:4,061483  5:3,284346  6:3,259792
Średnia:    1:3,280769  2:3,262230  3:3,275240  4:4,015545  5:3,201937  6:3,280459

Wnioski:
Każdy sposób wywołania funkcji doprowadzi nas do tego samego wyniku (zostanie wyświetlony ciąg znaków), jednakże wywołania nie są w pełni równoważne. Jak widać na zamieszczonej tabelce, wyniki wszystkich wywołań różnią się od siebie w bardzo niewielkim stopniu. Należy zauważyć, iż podany wynik dotyczy 10 tys. wywołań funkcji echo dla każdego sposobu. Zaoszczędzone kilka milisekund przy tylu wywołaniach to tak naprawdę niewielka optymalizacja.
Zatem podstawowy wniosek jest taki, iż nie należy się zbytnio przejmować sposobem użycia funkcji echo w kodzie PHP. Różnica w różnych wywołaniach funkcji jest niewielka, jednakże proszę zwrócić uwagę na sposób podwójnego użycia funkcji echo (kolumna nr. 4), z którego można wywnioskować, iż każde wywołanie funkcji echo kosztuje nas cenne milisekundy.
Zatem o ile sposób wywołania funkcji jest nieistotny, należy zadbać aby wywołań funkcji echo było jak najmniej!
Dodatkowo możemy wyłonić zwycięzcę (kolumna nr. 5): najszybsze wywołanie echo jest w formie: echo “${zmienna} testowany tekst”; – czyli zmienna ujęta w nawiasy klamrowe.

Powyższy test został oparty na tekscie w formacie ASCII (jak widać). Jednakże test na tekscie w formacie UTF-8 oraz ISO-8852-2 (latin 2), daje takie podobne wyniki jak dla tekstu ASCII.

Posted in Optymalizacja, PHP | Tagged , , , , , , , | 2 Comments

Jak zmienić hasło root w MySQL w systemie Windows?

Popularności bazy MySQL nikomu nie trzeba wyjaśniać (ale za to odpowiednie zabezpieczenie bazy już tak ;-). Jeżeli jesteś użytkownikiem bazy MySQL to na 100% od razu zaraz po instalacji twoja baza nie ma ustawionego hasła dla głównego administratora (użytkownik root).
Baza MySQL dostępna jest na wiele platform systemowych (Linux, Windows, Unix), ale miana hasła dla root’a oraz innych użytkowników we wszystkich systemach jest taka sama.
Proces zmiany hasła wygląda tak samo dla phpMyAdmina a także dla zmiany przy pomocy konsoli systemu operacyjnego.
Dlatego aby zobaczyć jak się zmienia hasło odsyłam do uniwersalnego artykułu na temat zmiany hasła w MySQL.

W tym artykule opisałem kilka sposobów zmiany hasła. Jest to na tyle uniwersalny przekład, iż pasuje on do większości systemów operacyjnych. Za pomocą tego artykułu zmienisz hasło dla root’a dla systemu Linux, oraz wszystkich Windowsów (Windows XP, Windows 7, 98, 2000, …).

Posted in Bezpieczeństwo, MySQL, Windows | Tagged , , , , , , | Leave a comment