Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Singleton] Wydajność
Astarot
post 3.05.2006, 08:18:34
Post #1





Grupa: Zarejestrowani
Postów: 90
Pomógł: 4
Dołączył: 5.02.2006

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


Witam, postanowiłem przetestować czas wykonywania skryptu dla klasy skonstruowanej wg. wzorca Singleton, wywoływanej poprzez metode statyczną która decyduje czy należy tworzyć nowy obiekt klasy. Wywoływałem tą klasę również w tradycyjny sposób. Czas wykonywania skryptu wyglądał
następująco :

Kod
Skrypt wykonany w czasie: 1.485986 sekundy (tradycyjnie wywołany obiekt)
Skrypt wykonany w czasie: 2.203427 sekundy(wg. singleton)


Byc moze zle implementuje ten wzorzec w swojej aplikacji wiec podaje poniżej kod :

  1. <?php
  2.  
  3. class Test2
  4. {
  5. public $licznik;
  6.  
  7. private static $oInstance = false;
  8.  
  9.  
  10. public static function getinstance ( )
  11. {
  12. if ( self::$oInstance == false )
  13. {
  14. self::$oInstance = new Test2( );
  15. }
  16. return self::$oInstance;
  17. }
  18. public function mnozenie()
  19. {
  20. return $this->licznik*10;
  21. }
  22. } 
  23.  
  24. ?>


Klasę wywołuję wg singleton tym kodem:

  1. <?php
  2.  
  3. for($i=0; $i<80000; $i++)
  4. {
  5. $test =& Test2::getinstance ( ); 
  6. $test->licznik=$test->licznik++;
  7. echo $test->mnozenie();
  8. }
  9.  
  10. ?>


A tak tworze obiekt klasy w tradycyjny sposób(wg. moich testów ten sposób jest szybszy)
  1. <?php
  2.  
  3. for($i=0; $i<80000; $i++)
  4. {
  5. $test = New Test2( ); 
  6. $test->licznik=$test->licznik++;
  7. echo $test->mnozenie();
  8. }
  9.  
  10. ?>


Czy może mi ktoś wyjaśnić dlaczego kod wg singleton jest wykonywany wolniej i kiedy warto
w swoich aplikacjach implementować ten wzorzec ?

Z góry dzieki za pomoc.


--------------------
torrenty
Go to the top of the page
+Quote Post
hwao
post 3.05.2006, 09:12:04
Post #2


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Roznica jest nie wielka.

Singleton jak sama nazwa wskazuje jest uzywany tam gdzie w calej aplikacji musi byc tylko jedna wersja obiektu i tego trzeba sie trzymac.
Go to the top of the page
+Quote Post
LBO
post 3.05.2006, 11:04:07
Post #3





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


Dodam tylko, że funkcjonalność tego wzorca jest na tyle duża, że pomija się raczej takie małe wady. O ile tę małą różnicę można nazwać wadą, bo wyobraź sobie jakie narzuty na czas wykonywania, miałoby przekazywanie obiektów przez parametr/referencję - bo właśnie temu singleton zapobiega.
Go to the top of the page
+Quote Post
mariuszn3
post 3.05.2006, 12:51:20
Post #4





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

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


Hmm.. a spróbuj taką wersję (przynajmniej to co napisałeś trochę mi nie pasuje):
Singleton:
  1. <?php
  2.  
  3. class TestSingleton {
  4. private $licznik = 0;
  5. private static $oInstance = false;
  6.  
  7. public static function set_instance() {
  8. if (self::$oInstance === false) {
  9. self::$oInstance = new Test2();
  10. ++self::$oInstance->licznik;
  11. }
  12. }
  13.  
  14. public static function mnozenie() {
  15. return self::$oInstance->licznik*10;
  16. }
  17. }
  18. for($i=0; $i<80000; ++$i) {
  19. TestSingleton::set_instance();
  20. echo TestSingleton::mnozenie();
  21. }
  22.  
  23. ?>


Tradycyjny sposób:
  1. <?php
  2.  
  3. class Test {
  4. private $licznik = 0 ;
  5.  
  6. public function __construct() {
  7. ++$this->licznik;
  8. }
  9.  
  10. public function mnozenie() {
  11. return $this->licznik*10;
  12. }
  13. }
  14.  
  15. for($i=0; $i<80000; ++$i) {
  16. $test = new Test;
  17. echo $test->mnozenie();
  18. }
  19.  
  20. ?>


Nie mówię, że będzie dużo lepiej, ale kod jakby właściwszy mi się wydaje.

Ten post edytował mariuszn3 3.05.2006, 15:18:20
Go to the top of the page
+Quote Post
Hacker
post 3.05.2006, 12:53:51
Post #5





Grupa: Zarejestrowani
Postów: 225
Pomógł: 0
Dołączył: 1.11.2005

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


Cytat(Astarot @ 2006-05-03 07:18:34)
Klasę wywołuję wg singleton tym kodem:

  1. <?php
  2.  
  3. for($i=0; $i<80000; $i++)
  4. {
  5. $test =& Test2::getinstance ( ); 
  6. $test->licznik=$test->licznik++;
  7. echo $test->mnozenie();
  8. }
  9.  
  10. ?>


A tak tworze obiekt klasy w tradycyjny sposób(wg. moich testów ten sposób jest szybszy)
  1. <?php
  2.  
  3. for($i=0; $i<80000; $i++)
  4. {
  5. $test = New Test2( ); 
  6. $test->licznik=$test->licznik++;
  7. echo $test->mnozenie();
  8. }
  9.  
  10. ?>

zły test, chociaż wyniki poprawne singleton jest trochę wolniejszy.
  1. <?php
  2. $test->licznik=$test->licznik++;
  3. ?>
nigdy nie zwiększy $test->licznik
$zmienna++ zwiększa wartość zmiennej PO użyciu, a nie PRZED
mój kod testujący
  1. <?php
  2. class Test2
  3. {
  4.  
  5. public $licznik = 1;
  6.  
  7. public static function getinstance()
  8. {
  9. static $instance;
  10. if (!isset($instance))
  11. $instance = new Test2();
  12. return $instance;
  13. }
  14. public function mnozenie()
  15. {
  16. return $this->licznik*10;
  17. }
  18. } 
  19.  
  20. class Test
  21. {
  22. public $licznik = 1;
  23.  
  24. public function mnozenie()
  25. {
  26. return $this->licznik*10;
  27. }
  28. }
  29. function getmicrotime()
  30. {
  31. list($usec, $sec) = explode(" ", microtime());
  32. return ((float)$usec + (float)$sec);
  33. }
  34. $temp = 0;
  35. $time_start = getmicrotime();
  36. for($i=0; $i<1000000; $i++)
  37. {
  38. $test = Test2::getinstance();
  39. $test->licznik=++$temp;
  40. $temp = $test->licznik;
  41. $test->mnozenie();
  42. }
  43. $time_end = getmicrotime();
  44. echo 'Singleton: '.($time_end-$time_start).'s <br>';
  45.  
  46. $temp = 0;
  47. $time_start1 = getmicrotime();
  48. for($i=0; $i<1000000; $i++)
  49. {
  50. $test = New Test( ); 
  51. $test->licznik=++$temp;
  52. $temp = $test->licznik;
  53. $test->mnozenie();
  54. }
  55. $time_end1 = getmicrotime();
  56. echo 'Normal: '.($time_end1-$time_start1).'s';
  57. ?>

a wyniki
Kod
Singleton: 8.5278367996216s
Normal: 6.6726980209351s

Takie wyniki uzystałem na moim AMD Athlon 2500+ (Barton)

-edit-
2 min później lol

Ten post edytował Hacker 3.05.2006, 12:55:22


--------------------
(\.../)This is Bunny
(O.o)Copy Bunny into your signature to help him...
(> <)...on his way to world domination
Go to the top of the page
+Quote Post
em1X
post 3.05.2006, 18:33:01
Post #6





Grupa: Zarejestrowani
Postów: 984
Pomógł: 41
Dołączył: 16.03.2002
Skąd: Płock

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


Przeciez w singletonie nie chodzi o wydajnosc, ale o to, zeby klasa nie mogla byc powielana wieloma obiektami!

Przypominam, ze powinien byc jeszcze zdefiniowany prywatny konstruktor (w twoim przypadku go nie ma i mozna tworzyc obiekty tej klasy)

Ten post edytował em1X 3.05.2006, 18:33:26


--------------------
eh, co polska wódka to polska wódka
Go to the top of the page
+Quote Post

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 Wersja Lo-Fi Aktualny czas: 14.08.2025 - 06:39