Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [JavaScript] Obiekty
zegarek84
post
Post #1





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


tak trochu się zastanawiałem i nie wiem czy są jakieś różnice w wydajności, bądź ważniejsze w sposobie rozwiązywania problemów niuanse... np. w necie większość konstrukcji obiektów wygląda w ten sposób:
[JAVASCRIPT] pobierz, plaintext
  1. java script:
  2. function obiekt($f)
  3. {
  4. var $c=$f||1;
  5. delete($f);
  6. alert($c);
  7. this.bzdura=function(b){$c*=b;};
  8. this.cos=function(){alert($c);};
  9. }
  10. b=new obiekt;
  11. g=new obiekt(4);
  12. b.bzdura(3);
  13. g.bzdura(10);
  14. g.cos();
  15. b.cos();
  16. void(0);
[JAVASCRIPT] pobierz, plaintext

no i właśnie a pro po publicznych metod i publicznych zmiennych odnośnie tego this.cokolwiek - akurat mi się nie wygodnie pisze, jakoś wolę taką konstrukcję bez this.cokolwiek i bez pisania new podczas tworzenia nowego obiektu:
[JAVASCRIPT] pobierz, plaintext
  1. java script:
  2. function obiekt($f)
  3. {
  4. var $c=$f||1;
  5. delete($f);
  6. alert($c);
  7. return {
  8. bzdura:function(b){$c*=b;},
  9. cos:function(){alert($c);}
  10. };
  11. }
  12. b=obiekt();
  13. g=obiekt(4);
  14. b.bzdura(3);
  15. g.bzdura(10);
  16. g.cos();
  17. b.cos();
  18. void(0);
[JAVASCRIPT] pobierz, plaintext

i tu moje pytanie - jak jest poprawniej, czy są jakieś znaczące tutaj różnice??...
może tak przy okazji jakieś linki do trudniejszych artykułów a ciekawszych z niuansami

z góry dziękuje ...

sorki za podbicie ale znalazłem jeden motyw w tym co ja używam a ktoś mógłby uznać to za wadę - brak zdefiniowanego instanceof - więc odrazu rozwiązanie na instance of without new (IMG:style_emoticons/default/winksmiley.jpg) - tu już może spowolnienie lekkie - na pętlę nie chce mi się sprawdzać - choć raczej nie powinno być gdyż jest zwrócona tylko referencja... a jak jest sporo metod publicznych to jednak wolę pisać jak w poście wyżej drugi przykład zamiast dla każdej metody poprzedzać this...

instance of without new (przykład na zdefiniowanie instancji):
Kod
java script:g=function(){};function c(){var ll=22; return {k:function(){return ll;}}};function a(ob,cialo){ob.prototype=cialo;return new ob;};h=a(g,c());alert(h instanceof g);void(0)

ps. aby instancja zosttała zwrócona to funkcja do której przyrównujemy czy istnieje instancja musi być w zasięgu w miejscu gdzie ją sprawdzamy...

dalej szukam jakichś za i przeciw który sposób lepszy - lub niech ktoś napisze, że to jeden h* (IMG:style_emoticons/default/winksmiley.jpg)

lub jeśli ktoś chce pisać new a nie chce co chwila pisać this wewnątrz gdyż woli notację json:
Kod
java script:g=function(){};function c(){var ll=22; return {k:function(){return ll;}}};g.prototype=c();h=new g;alert(h instanceof g);void(0)


Ten post edytował zegarek84 6.01.2010, 16:40:15
Go to the top of the page
+Quote Post
pp-layouts
post
Post #2





Grupa: Zarejestrowani
Postów: 53
Pomógł: 1
Dołączył: 28.09.2007
Skąd: Gdynia

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


Specjalnie dla Ciebie, wielki test:

[JAVASCRIPT] pobierz, plaintext
  1. function ms() {
  2. var d = new Date();
  3. return d.getTime();
  4. }
  5.  
  6. function benchmark(fn, iterations) {
  7. var time = ms();
  8. for (var i = 0; i < iterations; i++) fn();
  9. return ms() - time;
  10. }
  11.  
  12. function A(x) {
  13. this.y = x;
  14. this.t = function() {
  15. return this.y++;
  16. };
  17. };
  18.  
  19. B = function(x) {
  20. this.y = x;
  21. this.t = function() {
  22. return this.y++;
  23. };
  24. };
  25.  
  26. C = function(x) {
  27. return {
  28. y : x,
  29. t : function() {
  30. return this.y++;
  31. }
  32. };
  33. };
  34.  
  35. D = function(x) { this.y = x; };
  36. D.prototype = {
  37. y : null,
  38. t : function() {
  39. return this.y++;
  40. }
  41. };
  42.  
  43. iterations = 1000000;
  44.  
  45. td = benchmark(function() { d = new D(3); d.t(); }, iterations);
  46. tc = benchmark(function() { c = new C(2); c.t(); }, iterations);
  47. tb = benchmark(function() { b = new B(1); b.t(); }, iterations);
  48. ta = benchmark(function() { a = new A(0); a.t(); }, iterations);
  49.  
  50. alert("Wyniki: " + [ta, tb, tc, td].join(', ') + 'ms');
  51. alert("Sprawdzenie: " + [a.y, b.y, c.y, d.y].join(', '));
[JAVASCRIPT] pobierz, plaintext



Oto wyniki:

Firefox 3.6 beta 5: 5054, 6622, 5887, 2726 ms

Opera 10.10: 2102, 2079, 2925, 1381 ms

Chrome 4.0.249.43: 310, 302, 369, 75 ms

IE 8: 8085, 8315, 10457, 6007 ms

Są to średnie z 3 testów dla wszystkich przeglądarek z wyjątkiem IE, nie chciało mi się tyle czekać.

Zdecydowanym faworytem jest klasa utworzona z prototypu, czyli nasze D. Rozwiązanie z funkcją zwracającą obiekt © nie sprawdza się za dobrze w większości przeglądarek. Rozwiązania z funkcją i nieszczęsnym this-em (A i (IMG:style_emoticons/default/cool.gif) uzyskują podobny średni wynik, z przewagami zależnymi od przeglądarki.

Pewnie za wcześnie na poważne wnioski, ale ten banalny test wykazuje pewną wyższość konstrukcji z prototypem. Test sprawdza specyficzną rzecz - mianowicie szybkość tworzenia, inicjowania i użycia egzemplarza klasy. Innym razem trzeba sprawdzić jak będą kształtowały się profile wydajności w przypadku iteracji samego użycia egzemplarza, bez jego tworzenia. Sytuacja tworzenia egzemplarza w każdej iteracji jest raczej nietypowa - przez co niezbyt miarodajna.

Żeby zakończyć ten odcinek jakimś morałem - wydaje mi się, że ogólny wniosek płynący z tego doświadczenia - 1 ch. (IMG:style_emoticons/default/smile.gif) Są pewne różnice w wydajności, ale generalnie jeśli nie liczymy taktów procka jak w demie na C64 - style klas zostaną chyba w całości w kwestii upodobań danego programisty.

PS, mały update, sprawdziłem jeszcze

[JAVASCRIPT] pobierz, plaintext
  1. E = function(x) { this.y = x; };
  2. E.prototype.y = null;
  3. E.prototype.t = function() {
  4. return this.y++;
  5. }
[JAVASCRIPT] pobierz, plaintext



Uzyskuje nieznacznie gorsze wyniki od D we wszystkich przeglądarkach z wyjątkiem FF, gdzie wychodzi odrobinę szybciej, ale może to być mimo wszystko błąd pomiaru.

Myślę sobie, że silniki JS chyba optymizują jakoś definicje via prototype. Ja więc zostaję przy nich, z ulubionym stylem Class.prototype = JSON. (IMG:style_emoticons/default/smile.gif)

Go to the top of the page
+Quote Post
zegarek84
post
Post #3





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

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


może będzie ciekawa dyskusja (IMG:style_emoticons/default/winksmiley.jpg) ... i a pro po mi chodziło o troszku inny sposób tworzenia obiektów, coś ala jak obiekt C ale bez parametru new (i tu czas jest TNC zbliżony a nawet ciutkę szybszy od ta) , poza tym zawsze powinno się używać var gdyż inaczej zmienne lądują do globalnego window lub czasem powodują błędy jeśli w tym window nie były zdefiniowane - no chyba, że się chce przypisać wartość w window - ale wcześniej tam powinny być zdefiniowane...

pobawiłem się tym skryptem by wyciągnąć dodatkowe wnioski...
no nie trzeba było definiować w prototype pustej zmiennej y skoro jest w funkcji - czas też minimalnie szybszy...

jedna zasadnicza uwaga to w niektórych obiektach często się przydają (choć nie zawsze) zmienne prywatne (definiowane wewnątrz funkcji przez var), więc aby mieć dostęp do niektórych rzeczy zależnych od zmiennych prywatnych lub by móc je "ustawiać" to kilka metod prywatnych należało by zdefiniować w funkcji (i tu najszybciej wypada akurat definicja this.metoda/zmienna)...

wniosek - wszystkie publiczne metody korzystające z publicznych zmiennych/metod i tak jest najszybciej zdefiniować przez rozszerzenie konstruktorem prototype (jednak rozszerzając przez prototype nie mamy dostępu do zmiennych/funkcji prywatnych - chyba, że przez metody publiczne)

ps. w językach skryptowych szybszy jest zapis ++i od zapisu i++

ogólnie może jeszcze ktoś ciekawie podsumuje...
i masz niezły komputer ;p (testy zrobiłem z tym na operze 10.10 na suśle i czasy wyszły mniejsze ;p):
[JAVASCRIPT] pobierz, plaintext
  1. function ms() {
  2. var d = new Date();
  3. return d.getTime();
  4. }
  5.  
  6. function benchmark(fn, iterations) {
  7. var time = ms();
  8. for (var i = 0; i < iterations; i++) fn();
  9. return ms() - time;
  10. }
  11.  
  12. function A(x) {
  13. this.y = x;
  14. this.t = function() {
  15. return this.y++;
  16. };
  17. };
  18.  
  19.  
  20. var B = function(x) {
  21. this.y = x;
  22. this.t = function() {
  23. return this.y++;
  24. };
  25. };
  26. B.prototype={c:99};
  27.  
  28. var C = function(x) {
  29. return {
  30. y : x,
  31. t : function() {
  32. return this.y++;
  33. }
  34. };
  35. };
  36.  
  37. var D = function(x) { this.y = x; };
  38. D.prototype = {
  39. y : null,
  40. t : function() {
  41. return this.y++;
  42. }
  43. };
  44.  
  45. var G = function(x) { this.y = x; };
  46. G.prototype = {
  47. t : function() {
  48. return this.y++;
  49. }
  50. };
  51.  
  52. var F = function(x) {var ob=function(){};
  53. ob.prototype={
  54. y : x,
  55. t : function() {
  56. return this.y++;
  57. }
  58. };
  59. return new ob;
  60. };
  61.  
  62. var iterations = 1000000,
  63.  
  64.  
  65. tc = benchmark(function() {var c = new C(2); c.t(); }, iterations),
  66. TNC = benchmark(function() {var nc = C(9); nc.t(); }, iterations),
  67. TNG = benchmark(function() {var ng = new G(9); ng.t(); }, iterations),
  68. TNF = benchmark(function() {var nf = F(11); nf.t(); }, iterations),
  69. tb = benchmark(function() {var b = new B(1); b.t(); }, iterations),
  70. td = benchmark(function() {var d = new D(3); d.t(); }, iterations),
  71. ta = benchmark(function() {var a = new A(0); a.t(); }, iterations);
  72.  
  73. alert("Wyniki: " + [ta, tb, tc, td, TNC, TNG, TNF].join(', ') + 'ms');
  74. /*alert("Sprawdzenie: " + [a.y, b.y, c.y, d.y, nc.y].join(', ')); //teraz nie ma prawa bytu
  75. */
  76. /*
  77. Wyniki: 8516, 8094, 11139, 2888, 8439, 2630, 15315ms
  78. */
[JAVASCRIPT] pobierz, plaintext
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 21:13