Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Testy szybkości i ciekawe wyniki, Porównanie szybkości działania funkcji z parametrami różnego typu
gWd
post
Post #1





Grupa: Zarejestrowani
Postów: 55
Pomógł: 0
Dołączył: 17.09.2006

Ostrzeżenie: (0%)
-----


Wykonałem krótkie testy porównujące szybkości działania funkcji z parametrem przekazanym przez wartość, referencję i obiekt. Musze przyznać, że wyniki troche mnie zaskoczyły.

Środowisko:
PHP 5.2.1RC2
Apache 2.2.4

Przykład 1
  1. <?php
  2. class C1
  3. {
  4. public $data=array();
  5.  
  6. public function UstawZTablicy ($tab)
  7. {
  8. foreach ($tab as $key => $value)
  9. {
  10. $this->data[$key] = $value;
  11. }
  12. }
  13. public function ObjMet()
  14. {
  15. echo $this->data['pole8455'];
  16. }
  17. }
  18.  
  19. function Tab ($tab)
  20. {
  21. echo $tab['pole8455'];
  22. }
  23.  
  24. function TabRef (&$tab)
  25. {
  26. echo $tab['pole8455'];
  27. }
  28.  
  29. function ObjFunc ($obj)
  30. {
  31. echo $obj->pole8455;
  32. }
  33.  
  34. $tab = array();
  35. for ($ptl=1; $ptl<10000; $ptl++)
  36. {
  37. $tab['pole'.$ptl] = $ptl;
  38. }
  39. $obj = new C1();
  40. $obj->UstawZTablicy($tab);
  41.  
  42. $timeTests = array();
  43.  
  44. $timeTests[0]['czas'] = microtime(true);
  45. $timeTests[0]['znak'] = 'start';
  46.  
  47. //test funkcji z parametrem wartosciowym
  48. for ($ptl=0; $ptl<4000; $ptl++)
  49. {
  50. Tab($tab);
  51. }
  52.  
  53. $timeTests[4]['czas'] = microtime(true);
  54. $timeTests[4]['znak'] = 'Tab';
  55.  
  56. //test funkcji z przekazaniem jej parametru: obiekt
  57. for ($ptl=0; $ptl<4000; $ptl++)
  58. {
  59. ObjFunc($obj);
  60. }
  61.  
  62. $timeTests[1]['czas'] = microtime(true);
  63. $timeTests[1]['znak'] = 'ObjFunc';
  64.  
  65. //test metody obiektu
  66. for ($ptl=0; $ptl<4000; $ptl++)
  67. {
  68. $obj->ObjMet();
  69. }
  70.  
  71. $timeTests[2]['czas'] = microtime(true);
  72. $timeTests[2]['znak'] = 'ObjMet';
  73.  
  74. //test funkcji z parametrem referencyjnym
  75. for ($ptl=0; $ptl<4000; $ptl++)
  76. {
  77. TabRef($tab);
  78. }
  79.  
  80. $timeTests[3]['czas'] = microtime(true);
  81. $timeTests[3]['znak'] = 'TabRef';
  82.  
  83.  
  84. echo '<br />';
  85. $timePrev = 0;
  86. foreach ($timeTests as $time)
  87. {
  88. echo $time['znak'].': '.($time['czas'] - $timePrev).'<br />';
  89. $timePrev = $time['czas'];
  90. }
  91. ?>


Średnie wyniki z 10 pomiarów:
ObjFunc: 0,03630816936492920
ObjMet: 0,01625814437866210
Tab: 0,02549026012420650
TabRef: 0,01591291427612310

Opis wyników
ObjFunc jest 2x wolniejsze niż wywołanie metody obiektu ObjMet
Tab jest 1.6x wolniejsze od funkcji z parametrem referencyjnym!!!

Wnioski
1. Okazuje się, że wbrew dokumentacji PHP, przekazanie parametu przez referencję jest dużo szybsze niż przekazanie wartości. Należy się domyślać, że dotyczy to raczej zmiennych o dość rozmiarach.
2. Wywołanie metody obiektu jest znacznie szybsze niż (trochę dziwna) funkcja.

Drugi test jest jeszcze ciekawszy!
Tym razem modyfikujemy zmienną przekazaną do funkcji/metody.

Przykład 2
  1. <?php
  2. class C1
  3. {
  4. public $data=array();
  5.  
  6. public function UstawZTablicy ($tab)
  7. {
  8. foreach ($tab as $key => $value)
  9. {
  10. $this->data[$key] = $value;
  11. }
  12. }
  13. public function ObjMet()
  14. {
  15. $this->data['pole8455'] = 34534;
  16. }
  17. }
  18.  
  19. function Tab ($tab)
  20. {
  21. $tab['pole8455'] = 34534;
  22. }
  23.  
  24. function TabRef (&$tab)
  25. {
  26. $tab['pole8455'] = 34534;
  27. }
  28.  
  29. function ObjFunc ($obj)
  30. {
  31. $obj->pole8455 = 34534;
  32. }
  33.  
  34. $tab = array();
  35. for ($ptl=1; $ptl<10000; $ptl++)
  36. {
  37. $tab['pole'.$ptl] = $ptl;
  38. }
  39. $obj = new C1();
  40. $obj->UstawZTablicy($tab);
  41.  
  42. $timeTests = array();
  43.  
  44. $timeTests[0]['czas'] = microtime(true);
  45. $timeTests[0]['znak'] = 'start';
  46.  
  47. //test funkcji z parametrem wartosciowym
  48. for ($ptl=0; $ptl<4000; $ptl++)
  49. {
  50. Tab($tab);
  51. }
  52.  
  53. $timeTests[4]['czas'] = microtime(true);
  54. $timeTests[4]['znak'] = 'Tab';
  55.  
  56. //test funkcji z przekazaniem jej parametru: obiekt
  57. for ($ptl=0; $ptl<4000; $ptl++)
  58. {
  59. ObjFunc($obj);
  60. }
  61.  
  62. $timeTests[1]['czas'] = microtime(true);
  63. $timeTests[1]['znak'] = 'ObjFunc';
  64.  
  65. //test metody obiektu
  66. for ($ptl=0; $ptl<4000; $ptl++)
  67. {
  68. $obj->ObjMet();
  69. }
  70.  
  71. $timeTests[2]['czas'] = microtime(true);
  72. $timeTests[2]['znak'] = 'ObjMet';
  73.  
  74. //test funkcji z parametrem referencyjnym
  75. for ($ptl=0; $ptl<4000; $ptl++)
  76. {
  77. TabRef($tab);
  78. }
  79.  
  80. $timeTests[3]['czas'] = microtime(true);
  81. $timeTests[3]['znak'] = 'TabRef';
  82.  
  83.  
  84. echo '<br />';
  85. $timePrev = 0;
  86. foreach ($timeTests as $time)
  87. {
  88. echo $time['znak'].': ';
  89. echo ($time['czas'] - $timePrev).'<br />';
  90. $timePrev = $time['czas'];
  91. }
  92. ?>


Średnie wyniki z 10 pomiarów:
ObjFunc: 0,00535948276519776
ObjMet: 0,00558812618255616
Tab: 12,12336094379430000
TabRef: 0,00451698303222655

Opis wyników
ObjFunc i ObjMet mają bardzo zbliżone wyniki.
Zaskakuje natomiast funkcja Tab z wynikiem ponad 2000x gorszym od innych sposobów!!!! w tym od funkcji z parametrem referencyjnym.

Wnioski
1. Porównując wyniki z Przykładu 1 i 2 widzimy, że PHP wykonując funkcję z parametrem wartościowym nie tworzy kopii tego paremetru za każdym razem. Taka kopia generowana jest tylko wtedy, gdy zmienna ulega zmianie wewnątrz funkcji!
2. Przekazywanie do funkcji dużych zmiennych przez wartość jest wolniejsze niż przekazanie ich przez referencję, nawet jeśli zmienna nie ulega modyfikacji wewnątrz funkcji!
3. Wywoływanie i działanie fukcji/metod na obiektach może być nieco wolniejsze od funkcji na tablicach, ale różnica nie jest duża.

Ten post edytował gWd 18.04.2007, 12:19:17


--------------------
art of programming
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 14:45