Temat: js-object-create-vs-new-function

Witajcie :)
stworzyłem grę internetową online i staram się ją optymalizować
a mianowicie wiem tyle :
Object.create : kopiuje poprzednią wartość i przy tym zużywa więcej pamięci ale za to dostęp do obiektu jest szybszy
(sprawdzone jspref).
new function() : tworzy coś na wzór klasy dostęp jest wolniejszy ale zabiera mniej pamięci wszystko jest powiązane
tak w skrócie to co ja wiem to nie musi być poprawne ... :P
i teraz moje pytanie co jest bardziej wydajne do mojego projektu gdy mam
coś takiego aktualnie:
game = function()
{
this.start = function()
{
var player =[];
for (var k =0;k< iloscgraczy;k++)
{
player[k] =
{
x:0,
y:0,
id:0,
...
}
...
}
...
}...
}
var games[iloscgier] = new game(); //dodawanie nowej gry na server ta zmienna iloscgier to wszystkie gry
i lepiej zrobić playera jako this.player = function() ... czy var player = function() jako nastepna klase czy
zostawic jak jest ?? Z góry dziękuje za odpowiedz pozdrawiam rafras ;)Ten post został edytowany przez Autora dnia 25.09.15 o godzinie 14:31

konto usunięte

Temat: js-object-create-vs-new-function

Pytanie czy różnica w wydajności jest znacząca i czy jest to wzrost wydajności na wszystkich platformach czy zwyczajnie na konkretnej jest to kwestia optymalizacji danego elementu?

I czy tak często będzie żonglował obiektami że Ci się to opłaca?

Ja od dłuższego już czasu stosuje prostą zasadę.
1. wszystkie konstruktory nazywam z dużej litery
2. ZAWSZE stosuje operator "new". Dla wstecznej kompatybilności z dawnymi metodami w pierwszej linii konstruktora zaszywam instanceof i w razie czego tworzę obiekt. Więc działa zarówno "var x = new Thing()" jak i "var x = Thing()" gdzie to drugie jest stanowczo niezalecane.

A dlaczego? Z prostej przyczyny. Jak ECMAScript 6 wejdzie do powszechnego użycia (gdzie na Nodzie już jest więc czekamy na przeglądarki), mamy do dyspozycji między innymi klasy. A te wręcz wymagają użycia "new".
Co za tym idzie - stosuje new z uwagi na to że chce mieć jednakowe zachowanie w całym środowisku.

Temat: js-object-create-vs-new-function

Dariusz Półtorak dzięki za odpowiedz widzę profesjonalista ;)
Wszystkie skrypty które napotykam są zrobione przez powiedzmy "klasy" czyli właśnie
var player = function()
{}; i zadeklarowanie var players = new player(); lecz dostęp do konstruktora tej "klasy" jest znacznie wolniejszy niż w przypadku zwykłego obiektu :)
https://jsperf.com/high-speed-functions/4
np:
var test =
{
x:10,
y:10,
f:function ()
{.....
}
}
var testy = Object.create( test);
testy.x = 20;
jest szybszy niż
var test = function()
{
this.x = 10;
this.y = 10;
this.f = function ()
{.....
};
} ;
var testy = new test();
testy.x = 20;
w moim projekcie tworze dla każdego gracza osobny skopiowany obiekt dzięki temu przy odświeżaniu co 10 ms dostęp do wartości jest dużo szybszy ale jak to się będzie miało do większej ilości ludzi np 100 gier z tego w każdej grze po 4 graczy.Czy zużycie ramu będzie gigantyczne przez to spadnie cała wydajność? w funkcji odświeżania odwołuje się do niej praktycznie cały czas co 10ms w każdej grze. trochę mnie to niepokoi bo wszystkie poważniejsze projekty są zrobione na zasadzie właśnie "klasy" :)

wielu programistów robi takie coś: ( co jest według mnie zapychaniem ramu i spowolnieniem wykonywania)

var test = function()
{
this.x = 10;
this.y = 10;
this.getx = function ()
{
return this.x;
};
} ;
i aby dostać się do wartości wybierają this.getx zamiast this.x co jest strasznie powolne.
Będę wdzięczny za naprowadzenie mnie na dobre rozwiązanie.

Pozdrawiam i Dziękuje Rafras ;DTen post został edytowany przez Autora dnia 25.09.15 o godzinie 14:38

konto usunięte

Temat: js-object-create-vs-new-function

Jezeli możesz to używaj [ code ] do pokazywania kodu


if (1 == 2) {
return true;
}


ciężko się czyta to co piszesz. Ja na Twoim miejscu upewnił się że to co robisz ma wystarczająco dużą skalę żeby takie optymalizacje miały sens. Przykładowo mam jedną grę w projektach. Serwer ma pętlę zdarzeń która odświeża się około 60 razy na sekundę.

W trakcie jednego przejścia (okienko to około 16ms) jestem w stanie wykonać setki tysięcy instrukcji.

Musiałbyś mieć BARDZO złożoną grę żeby nie zmieścić się w takim okienku. Najwolniejszą częścią Twojej gry zapewne jest rysowanie sceny. Sugeruje wszelkie obliczenia puszczać na jednej pętli a rysowanie robić na drugiej. Niech korzysta z danych wynikowych z pierwszej pętli i niech obie działają niezależnie.

Swoją drogą jak czytam ten Twój kod to myślę że problemem jest przede wszystkim alokacja pamięci ale to musisz sprawdzić. W momencie uruchomienia programu, silnik JS nie ma informacji że "test" zawiera x oraz y kiedy zrobisz to przez konstruktor. W wypadku gdy zrobisz obiekt json który już na starcie je posiada (twoja metoda), ten problem nie występuje.

Bardzo łatwo można zauważyć ten efekt przy tablicach. Zrób sobie array na 100000 elementów dokładając do pustego arraya po 1 elemencie. JS będzie regularnie rezerwował pamięć czy nawet przenosił całość tam gdzie będzie miał odpowiednią ilość miejsca co sprawi że cały proces będzie niemiłosiernie wolny.

Teraz zrób to samo ale stwórz pusty array na 100000 elementów (wypełniony nullami) a następnie go uzupełnij. Będzie to dużo szybsze.

Co za tym idzie, spróbuj sposób z konstruktorem ale przygotuj go odpowiednio;


function Test() {}
test.prototype.x = 0;
test.prototype.y = 0;

var f = new Test();


Teraz interpreter powinien mieć na starcie informacje o x i y. Ja niestety nie mam teraz czasu tego sprawdzać.Ten post został edytowany przez Autora dnia 25.09.15 o godzinie 16:06

Temat: js-object-create-vs-new-function

Dariusz Półtorak Dzięki dobry pomysł zastosuje var arr = new Int32Array(x); i zadeklaruje obiekty w json :) a tu zrobiłem mały test :P i wychodzi na to że korzystanie z czystego obiektu jest optymalne :)


Obrazek

//testmc
var express = require('express'),
app = express(),
server = require('http').createServer(app);

server.listen(3000);

var test = function()
{
this.x = 0;
this.y = 0;

};


var ar =[];
var f =-1;
var fi = 0;
var las =0;
var sum= las-fi;
//
/*
setInterval(function (){
f++;
//for (var s; s<10000;s++)
ar[f] = new test();
console.log(f +" zadeklarowany class. uzycie ramu "+ process.memoryUsage().heapUsed );
},100);
// */
// /*

for (var s =0; s<=10000000;s++)
{
f++;
if (s==0) fi = process.memoryUsage().heapUsed;
if (s==10000000) las = process.memoryUsage().heapUsed;
ar[f] = new test();
ar[f].x +=1;
ar[f].y +=2;
}
console.log (fi/1000000+" "+las/1000000+ "zuzycie ramu dla "+s+" class to "+ (las-fi)/1000000);
console.log(las = process.memoryUsage());
// */

//testm
var express = require('express'),
app = express(),
server = require('http').createServer(app);

server.listen(3000);

var test =
{
x : 0,
y : 0
};



var ar =[];
var f =-1;
var fi = 0;
var las =0;
var sum= las-fi;
//
/*
setInterval(function (){
f++;
//for (var s; s<10000;s++)
ar[f] = Object.create( test);
console.log(f +" zadeklarowany obiekt. uzycie ramu "+ process.memoryUsage().heapUsed );
},100);
// */
// /*
for (var s =0; s<=10000000;s++)
{
f++;
if (s==0) fi = process.memoryUsage().heapUsed;
if (s==10000000) las = process.memoryUsage().heapUsed;
ar[f] = Object.create( test);
ar[f].x +=1;
ar[f].y +=2;
}
console.log (fi/1000000+" "+las/1000000+ " zuzycie ramu dla "+s+" obj to "+ (las-fi)/1000000);
console.log(las = process.memoryUsage());
// */

Dzięki za pomoc pozdrawiam Rafras ;)

konto usunięte

Temat: js-object-create-vs-new-function

Mam durne pytanie, dlaczego stosujesz jednocześnie notacje json i Object.create? To troszkę nie trzyma się kupy. W pierwszym przypadku dostaniesz obiekt który ma x i y jako propery a w drugim - obiekt który ma w łańcuchu prototypu x i y.

Powinieneś też zdawać sobie sprawę że używanie obiektów w ten sposób znacząco utrudni Ci pracę kiedy cokolwiek piszesz się deczko rozrośnie bo w zasadzie tracisz informację o typach. Wszystko będzie po prostu typu Object. Dziedziczenie też będzie kłopotliwe. W końcu Json został zaprojektowany przede wszystkim jako nośnik danych.

konto usunięte

Temat: js-object-create-vs-new-function

Dariusz P.:
Mam durne pytanie, dlaczego stosujesz jednocześnie notacje json i

Pomimo nieczytelności wklejonego kodu próbuję dopatrzeć się tam notacji JSON i mam problem. Wskażesz mi gdzie ją widzisz?Ten post został edytowany przez Autora dnia 27.09.15 o godzinie 05:40

konto usunięte

Temat: js-object-create-vs-new-function

Piotr L.:
Dariusz P.:
Mam durne pytanie, dlaczego stosujesz jednocześnie notacje json i

Pomimo nieczytelności wklejonego kodu próbuję dopatrzeć się tam notacji JSON i mam problem. Wskażesz mi gdzie ją widzisz?

Drugi przykład, chodzi mi dokładnie o ten fragment:


var test = {
x: 0,
y: 0
};
// a później
ar[f] = Object.create( test);
// zamiast
ar[f] = {
x: 0,
y: 0
}


Btw, nadal nie jestem przekonany do tej metody. O ile wypada szybciej o tyle później będzie kłopot z masą rzeczy zaczynając od instanceof. Będziesz musiał do każdego json-a dokładać dodatkowe dane żeby identyfikować co w nim faktycznie siedzi.

Temat: js-object-create-vs-new-function

Te dwa kody wklejone to akurat są na szybko napisane testy zużycia pamięci (bez użycia json,a to jest testowanie strikte "classy" vs " obiektu") . json użyje w swoim serwerze jako ze tak się wyrażę nośnik danych czyli kiedy gracz wchodzi na stronę ma wybór stworzenia gry lub dołączenia do losowej lub zagrania z znajomym . Kiedy jest full zgłoszonych użytkowników w grze, zaczyna się dana gra na początku jest inicjowana scena czyli tworzenie tablicy lokalnej w grze:
 var  gracze =  new Int32Array(<iloscgraczy>);

a następnie przydzielenie każdemu graczowi obiektu z json (cos jako wzór)np:
otrzymam do 2 graczy takie coś:
gracz[0]=<obj_z_jsona>;
gracz[1]=<obj_z_jsona>;


//bo
gracz[0] = <obj_z_jsona>;
// to jest to samo co
gracz[0]=object.create(<obj_z_jsona>);

no i potem reszta... losowanie pięter,losowanie skrzynek ,itd a następnie jest odpalana pętla odświeżająca grę która działa właśnie cały czas na tych obiektach
Tak w skrócie działanie mojej gry :) myślę ,że korzystanie z czystego obiektu jest lepsze bo w moim przypadku wiele razy działam na obiektach graczy a zużycie ramu jest trochę większe niż w przypadku "klasy" :)Teraz mam problem z wyciekiem pamięci :/ to prawdopodobnie właśnie przez to korzystanie z metody "obiektu" . Nie wiecie jak zwolnić pamięć w node? tu próbuje nadpisać null wyciąć indexy i nic wręcz ram jest bardziej zapychany :/


var express = require('express'),
app = express(),
server = require('http').createServer(app);

server.listen(3000);
var testf =
{
d :["asd23","sdfsdf"],
s :function(f,l)
{
var o = {x:f,y:l};
}
},
ar =[];
var f =-1;
var fi = 0;
var las =0;
var sum= las-fi;
function k(){
for (var s =0; s<=100;s++)
{
f++;
if (s==0) fi = process.memoryUsage().heapUsed;
if (s==1000000) las = process.memoryUsage().heapUsed;
ar[s] = testf; //Object.create( testf);
ar[s].d[0] = s+"asd";
ar[s].s(s,s); //ar[f].y +=2;
}
console.log (fi/1000000+" "+las/1000000+ " zuzycie ramu dla "+s+" obj to "+ (las-fi)/1000000);
console.log( process.memoryUsage());
}
k();
setTimeout(function()
{
ar.splice(0,1000000); //nie oczyszcza
ar=null; //nie oczyszcza
console.log ("czyszczenie" );
console.log( process.memoryUsage());
},15000);

Dziękuje pozdrawiam Rafras :)Ten post został edytowany przez Autora dnia 28.09.15 o godzinie 08:28

konto usunięte

Temat: js-object-create-vs-new-function

Dariusz P.:
Piotr L.:
Dariusz P.:
Mam durne pytanie, dlaczego stosujesz jednocześnie notacje json i

Pomimo nieczytelności wklejonego kodu próbuję dopatrzeć się tam notacji JSON i mam problem. Wskażesz mi gdzie ją widzisz?

Drugi przykład, chodzi mi dokładnie o ten fragment:


var test = {
x: 0,
y: 0
};
// a później
ar[f] = Object.create( test);
// zamiast
ar[f] = {
x: 0,
y: 0
}


Btw, nadal nie jestem przekonany do tej metody. O ile wypada szybciej o tyle później będzie kłopot z masą rzeczy zaczynając od instanceof. Będziesz musiał do każdego json-a dokładać dodatkowe dane żeby identyfikować co w nim faktycznie siedzi.

To nie jest JSON notation.. To Object Literal (w sumie to inna, krótsza forma zapisu "new Object()"). I fakt, z racji tego, że Object Literal jest Singletonem, nie da się robić jego wielu instancji. Z drugiej strony: zajmuje mało miejsca w pamięci. I jak wiele rzeczy w JS ma swoje wady i zalety ;)

A tak a propos wydajności i jej mierzenia, to polecam te wideo, nieco zmienia spojrzenie na JSPerf:
https://www.youtube.com/watch?v=65-RbBwZQdU
I należy pamiętać: "Premature optimization is as useful as premature ejaculation" :)

konto usunięte

Temat: js-object-create-vs-new-function

Wybacz ale kod który wklejasz jest nieczytelny. Trzeba to za każdym razem przepuszczać przez formatter :P

Główna przyczyna wycieków pamięci to na ogół trzymanie obiektów które mają referencje do siebie nawzajem. Node od jakiegoś czasu wspiera ES6 więc sugeruje korzystać z weak mapy. W zasadzie przez ostatni rok miałem okazję 3 razy "naprawiać" nodowy soft i na ogół to była przyczyna.

GC działa niezależnie od programisty. Powinien czyścić pamięć kiedy uzna że coś nie jest potrzebne. Można wymusić jego użycie poprzez funckję gc();. Masz do niej dostęp jak uruchomisz node z flagą --expose-gc. Ale generalnie nie polecam. Ja to używam jako tzw "panic button". W moim wypadku okresowo sprawdzam zużycie pamięci w aplikacji. Jeżeli jest zbyt wysokie, próbuje odpalić GC ale wcześniej powiadamiam siebie (lub admina) możliwymi drogami że coś jest solidnie spieprzone.

@Piotr, bardzo fajny materiał :-) Dzięki.

konto usunięte

Temat: js-object-create-vs-new-function

Raf R.:

W kontekście optymalizacji taki temat słabo wygląda.

Gdyby to był temat do dyskusji na temat tworzenia obiektów "po chińsku" to co innego. Wtedy można bić brawo, że ktokolwiek na grupie słyszał o takich rozwiązaniach, albo chociaż czytał, bo jak ma możliwość zastosowania w praktyce i jeszcze rozumie co robi, to już w ogóle szczyt sukcesu.

Możliwe, że takie serwisy jak facebook, czy google mogą starać się doszukiwać optymalizacji wszędzie. Aczkolwiek jak ktoś używa facebook'a to pewnie widzi, że w kwestii optymalizacji jest jeszcze wiele do zrobienia gdzie indziej.

Następna dyskusja:

Event.observe is not a func...




Wyślij zaproszenie do