Otwieranie / zamykanie tagów i wydajność?


91

To może być głupie pytanie, ale jako ktoś stosunkowo nowy w PHP, zastanawiam się, czy są jakieś problemy z wydajnością związane z częstym otwieraniem i zamykaniem tagów PHP w kodzie szablonu HTML, a jeśli tak, jakie mogą być najlepsze praktyki w zakresie pracy z tagami PHP?

Moje pytanie nie dotyczy ważności / poprawności zamykania tagów ani tego, który typ kodu jest bardziej czytelny niż inny, ale raczej o to, jak dokument jest analizowany / wykonywany i jaki może mieć wpływ na wydajność.

Aby to zilustrować, rozważ następujące dwie skrajności:

Mieszanie tagów PHP i HTML:

<?php echo
   '<tr>
       <td>'.$variable1.'</td>
       <td>'.$variable2.'</td>
       <td>'.$variable3.'</td>
       <td>'.$variable4.'</td>
       <td>'.$variable5.'</td>
   </tr>'
?>
// PHP tag opened once

Oddzielanie tagów PHP i HTML:

<tr>
   <td><?php echo $variable1 ?></td>
   <td><?php echo $variable2 ?></td>
   <td><?php echo $variable3 ?></td>
   <td><?php echo $variable4 ?></td>
   <td><?php echo $variable5 ?></td>
</tr>
// PHP tag opened five times

Chciałbym usłyszeć kilka opinii na ten temat, nawet jeśli chodzi tylko o to, aby usłyszeć, że nie ma to znaczenia.

Dzięki.


9
Ciekawe pytanie, +1 za to. Chociaż nie wydaje mi się, że dwa przykłady, które podałeś, są idealną parą do porównania, rozumiem sedno :)
okw

Dzięki ... Tak się składa, że ​​w tej chwili pracuję z ogromną tabelą html, a pytanie w pewnym sensie wpatruje się we mnie ... nawet jeśli jest trochę teoretyczne.
Tom

Poza tematem: Do zapełnienia tabeli należy użyć pętli i tablicy / iteratora danych.
Godny Dabbler

@fireeyedboy ... oczywiście, zgadzam się, ale nie zawsze jest to praktyczne. Albo wymaga akrobatyki podczas pobierania danych z bazy danych, albo struktura HTML nie pasuje do pętli.
Tom

4
Myślę, że czytelność jest tutaj najważniejsza. Nie zobaczysz żadnego większego wzrostu / spadku z czymś tak trywialnym jak to.
Chuck Le Butt

Odpowiedzi:


88

3 proste zasady, aby zrobić to dobrze:

  • Żaden problem ze składnią nie wpływa na wydajność. Tak działa manipulacja danymi.
  • Mów o wydajności popartej jedynie wynikami profilowania .
  • Przedwczesna optymalizacja jest źródłem wszelkiego zła

Problemy z wydajnością są dość trudne do zrozumienia. Zaleca się, aby nowicjusze nie brali tego pod uwagę. Ponieważ zawsze są pod wrażeniem drobiazgów i nie widzą naprawdę ważnych rzeczy. Tylko z powodu braku doświadczenia.

To samo dotyczy twojego pytania. Wyobraź sobie, że kiedykolwiek dostaniesz jakąś różnicę. Nawet duża, powiedzmy, jedna metoda jest 2 razy szybsza. Ojej, 2 razy! Wybrałem to i dobrze zoptymalizowałem moją aplikację, będzie teraz działać o 50% szybciej!

Źle . Nie 50%. Nigdy nie zauważysz ani nie zmierzysz tego wzrostu prędkości. Ponieważ zoptymalizowałeś część, która zajmuje tylko 0,0001% całego czasu wykonywania skryptu.

Jeśli chodzi o duże tabele HTML, renderowanie go przez przeglądarkę zajmuje dużo czasu . Znacznie więcej niż wygenerowałeś.

Profilowanie to kluczowe słowo w świecie performansu. Można bez wątpienia odrzucić każde pytanie związane z wydajnością, jeśli nie ma w nim słowa „profilowanie”. Jednocześnie profilowanie nie jest nauką o rakietach. Po prostu mierzę czas działania różnych części twojego skryptu. Można to zrobić za pomocą jakiegoś profilera, takiego jak xdebug, lub nawet ręcznie, używając microtime(1). Dopiero po wykryciu najwolniejszej części możesz zacząć od testów.

Naucz się profilować przed zadawaniem pytań dotyczących wydajności. I naucz się nie zadawać pytań dotyczących wydajności, jeśli nie ma ku temu prawdziwych powodów.

Przedwczesna optymalizacja jest źródłem wszelkiego zła - D.Knuth .


4
Dlaczego jest tak źle, gdy używam słowa „punkt odniesienia” zamiast „profil”? Czy jest jakaś różnica w znaczeniu?
Byłbym

+1 za cytowanie Donalda Knutha i +200 za bardzo wnikliwą odpowiedź.
Clement Herreman

@nikic, Kiedy Col powiedział, że źle jest użyć słowa „benchmark”? Wygląda na to, że wkładasz mu słowa do ust lub odnosisz się do czegoś w niewłaściwym miejscu.
Chuck Le Butt

10
dlaczego jest to tak wysoko oceniane? Nie odpowiada na pytanie w żadnym kształcie ani formie. -1 ode mnie.
bharal

2
@NikiC Zwykłe użycie, którego byłem świadkiem: benchmarking oznacza w jakiś sposób pomiar lub ranking ogólnej wydajności fragmentu kodu w celu porównania go z alternatywnymi rozwiązaniami (jak to, co zrobił Amien w swojej odpowiedzi na to pytanie poniżej), podczas gdy profilowanie oznacza dowiedzieć się, które części kodu są odpowiedzialne za każdy widoczny dla użytkownika problem z wydajnością, który próbujesz rozwiązać. Różnica polega na tym, że profilowanie polega na określeniu przyczyny problemu z wydajnością, podczas gdy benchmarking polega na testowaniu jego rozwiązań.
Mark Amery,

40

Ponownie przeprowadziłem testy z 50000 wierszami i dodałem również metodę multi echo w 1 tagu

for ($j=0;$j<30;$j++) {
    foreach ($results as $key=>$val){
    ?>
       <tr>
           <td><?php echo $results[$key][0]?></td>
           <td><?php echo $results[$key][1]?></td>
           <td><?php echo $results[$key][2]?></td>
           <td><?php echo $results[$key][3]?></td>
           <td><?php echo $results[$key][4]?></td>
           <td><?php echo $results[$key][5]?></td>
           <td><?php echo $results[$key][6]?></td>
           <td><?php echo $results[$key][7]?></td>
           <td><?php echo $results[$key][8]?></td>
           <td><?php echo $results[$key][9]?></td>
           <td><?php echo $results[$key][10]?></td>
           <td><?php echo $results[$key][11]?></td>
           <td><?php echo $results[$key][12]?></td>
           <td><?php echo $results[$key][13]?></td>
           <td><?php echo $results[$key][14]?></td>              
       </tr>
    <?php 
    }
}

duration1: 31.15542483 sekund

for ($k=0;$k<30;$k++) {
    foreach ($results as $key1=>$val1){
        echo
           '<tr>
               <td>'.$results[$key1][0].'</td>
               <td>'.$results[$key1][1].'</td>
               <td>'.$results[$key1][2].'</td>
               <td>'.$results[$key1][3].'</td>
               <td>'.$results[$key1][4].'</td>
               <td>'.$results[$key1][5].'</td>
               <td>'.$results[$key1][6].'</td>
               <td>'.$results[$key1][7].'</td>
               <td>'.$results[$key1][8].'</td>
               <td>'.$results[$key1][9].'</td>
               <td>'.$results[$key1][10].'</td>
               <td>'.$results[$key1][11].'</td>
               <td>'.$results[$key1][12].'</td>
               <td>'.$results[$key1][13].'</td>
               <td>'.$results[$key1][14].'</td>              
           </tr>';
    }
}

czas trwania2: 30,23169804 sekund

for ($l=0;$l<30;$l++) {
    foreach ($results as $key2=>$val2){     
           echo'<tr>';
               echo'<td>'.$results[$key2][0].'</td>';
               echo'<td>'.$results[$key2][1].'</td>';
               echo'<td>'.$results[$key2][2].'</td>';
               echo'<td>'.$results[$key2][3].'</td>';
               echo'<td>'.$results[$key2][4].'</td>';
               echo'<td>'.$results[$key2][5].'</td>';
               echo'<td>'.$results[$key2][6].'</td>';
               echo'<td>'.$results[$key2][7].'</td>';
               echo'<td>'.$results[$key2][8].'</td>';
               echo'<td>'.$results[$key2][9].'</td>';
               echo'<td>'.$results[$key2][10].'</td>';
               echo'<td>'.$results[$key2][11].'</td>';
               echo'<td>'.$results[$key2][12].'</td>';
               echo'<td>'.$results[$key2][13].'</td>';
               echo'<td>'.$results[$key2][14].'</td>';              
           echo'</tr>';
    }
}

duration3: 27,54640007 sekund

Niewielka różnica między oryginalnymi 2 metodami, ale wygląda na to, że jest trochę szybsza z mniejszą liczbą konkatenacji @poke

Ponieważ wątpię, czy będę potrzebować tak dużej ilości danych za jednym razem, myślę, że nadal będę używać wielu tagów, wcięcia kodu będą wyglądać schludniej, a układ „wyświetl źródła” będzie dokładniejszy


1
Trzecim przypadkiem testowym byłoby użycie wielu instrukcji echo z jednym znacznikiem php, ponieważ nie trzeba wtedy używać konkatenacji ciągów.
szturchnij

Ponownie przeprowadziłem testy z 50000 wierszami i dodałem również metodę multi echo w 1 tagu
Amien

5
+1 Mesuring jest ważny, gdy chcemy zoptymalizować. Często zdajemy sobie sprawę, że tego rodzaju optymalizacja jest bezużyteczna.
Luc M

18
Wygląda na to, że pierwsze dwa przykłady dają znacznie więcej białych znaków niż ostatni przykład. Może to być przyczyną dłuższego czasu wykonywania.
Mike C

echoAkceptuje również wiele wyrażeń do wyprowadzenia. Żaden wariant z tą funkcją nie został uwzględniony w danych.
hakre

13

Możesz łatwo zignorować różnicę w wydajności między tymi dwoma. Przy dzisiejszych nowoczesnych zasobach obliczeniowych różnica naprawdę nie ma znaczenia. Tego rodzaju rzeczy drukowane na ekranie naprawdę nie są powodem do zmartwień. Jest mnóstwo innych rzeczy, które powinieneś rozważyć wcześniej. Poza tym zawsze toczy się debata między najlepszą wydajnością a łatwością utrzymania kodu. Nie zawsze możesz starać się osiągnąć najlepszą wydajność. Zamiast tego należy zawsze brać pod uwagę obawy dotyczące wydajności oraz ilość czasu, jaki należy poświęcić na ich ulepszanie.


6

Kod, który można łatwo przetłumaczyć na pseudokod, jest lepszy. Świadczą o tym powyższe przykłady. Co zajmuje więcej czasu?

"Start php, do this 30 times:, then stop php.  Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php..."

"Start php, do this 30 times: print this, then add this to that, then add this to that, then add this to that, then add this to that, then add this to that, then add this to that..."

"Start php, do this 30 times: print this, print this, print this, print this, print this, print this, print this..."

Osobiście zrobiłbym:

"Start php, define this, do this 30 times: add this to that.  Print." 

Techniczne wyjaśnienie, jak działa tłumacz i dlaczego jedna droga jest szybsza od innej, nie ma znaczenia dla początkującego. Najlepiej po prostu poznać praktyczne zasady:

  1. Prostsze znaczy lepsze.
  2. Jeśli nie mieści się na jednej stronie, robi za dużo (podziel go).
  3. Jeśli nie możesz ręcznie zapisać pseudokodu na karcie indeksu, jest to zbyt skomplikowane.

Użyj więcej tagów, jeśli ogólny wynik jest prostszy. Kropka.


5

Prawdziwym problemem jest użycie pamięci. Łączenie łańcuchów i echo masowe mogą wykładniczo zwiększyć użycie pamięci.

Jeśli spamujesz tag php, kod staje się nieczytelny.

Najlepszym rozwiązaniem jest użycie silnika szablonów i całkowite uniknięcie mieszania kodu i prezentacji.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.