Omezená dědičnost (je něco lepšího než OOP?)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #300 kdy: 14. 09. 2015, 12:54:06 »
Ty dvě počítané vlastnosti jsou tam zcela zbytečné. A co je zbytečné, musí pryč.
Ty počítané vlastnosti rozhodně nejsou zbytečné. Slouží k tomu aby šel čtverec použít všude tam, kde se dá použít rovnoběžník. Pokud mám třeba funkci na kreslení rovnoběžníka, tak pokud má čtverec tyhle dvě "zbytečné" vlastnosti tak ho tímhle způsobem můžu nakreslit taky.

Nebo chci přidat funkci pro obvod. Ve tvém případě musím tu funkci dodat do interface a doimplementovat ve všech odvozených třídách. Není jednodušší napsat jedinou funkci, která spočítá obvod rovnoběžníka a v případě čtverce využívá ty "zbytečné" počítané vlastnosti?

Jak uz od zacatku tady nekdo rikal, vsechno zavisi na zpusobu pouziti.
Tyhle zobecnovani, co tady delas zas vedou tomu, ze casto to co kompl zvladl pred 20 lety s tehdejsim hw, dela dneska na 20 let novejsim hw stejnou dobu. Kdyz budes mit miliardy ctvercu a budes je nekde muset skladovat a budes potrebovat pocitat jejich obsahy, tak si sakra rozmyslis, jestli tam budes nekde pocitat cos, drzet si zbytecne data, atp.

Odtud pak vznikaji napriklad tragicke aplikace v Jave - nepouzitelny lagovaci moloch, prestoze Java sama o sobe umi byt i relativne hodne rychla.

P.S. sizeof(Parallelogram) = strideof(Parallelogram) = 24 a světe div se, sizeof(Square) = strideof(Square) = 8


BoneFlute

  • *****
  • 2 046
    • Zobrazit profil
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #301 kdy: 14. 09. 2015, 13:27:21 »
Nezapomínej, že to rozdělení musí být logické, ne adminstrativní.
Logicke rozdeleni to je z pohledu vykonu - pri kazde zmene chunku (napr. zniceni bloku) je treba znovu vytvorit mesh (3d "model" chunku, rendrovat blok po bloku to opravdu nejde, vytvori se jen model s viditelnymi stranami bloku), coz je draha operace a pri nevhodne velikosti to povede k vykonostnim problemum (velky chunk -> casteji a dlouho se generuje, maly chunk -> vice rezie).

A klidně to můžeš dělat i během života (postaví zeď atd).
Po pravde, az takto dynamicke rozdelovani sveta zni velmi narocne. Kdyz si vezmu, ze jen hloupy algoritmus pro svetlo (trivialni flood-fill, navic s podstatne nizsim polomerem nez je napr. dostrel luku) pusobi vykonostni problemy.

Chyba v úvaze je v tom, že předpokládáš, že ten objekt něco renderuje.

Logické rozdělení je to z pohledu toho, zda se mohou elementy ovlivňovat.

Zkus si představit jednoduché lineární pole objektů (pańáců a pomerančů). Pak můžeš mět jakýsi strom, který určuje, kde se které větve mohou ovlivňovat. Sourozence můžeš paralelizovat (když si to čtu, tak to zní děsivě, ale popisuji spíše potenciál, protože v praxi by to byl spíš takovej keř). A v každém ticku se ti v tom stromu provedou výpočty a v kořeni ti vypadne seznam všech změn, které musíš provést na scéně. Až tady máš to místo, kde budeš renderovat. A kde můžeš perfektně optimalizovat (zničení chunku, a vygenerování už finálního se všemi elementy, renderování jen viditelné scény, atd). A díky tomu, že mám seznam všech změn, mohu zkusit paralelizovat i to renderování.

Jak by se to dalo dělat lépe? JS navrhoval Monády, ale (pravděpodobně díky nedostatku zkušeností) bych se bál aby mi z toho nevylezl podobnej nepřehlednej mrdník, jaký obhajuje gamer u svého mutable řešení.


Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #302 kdy: 14. 09. 2015, 14:07:18 »
Řekněme, že chci mít objekty čtverec, obdélník, kosočtverec a rovnoběžník. Je jasné, že s jednoduchou dědičností se daleko nedostanu. Proto obecný dotaz: existuje nějaké ... ?

... Omezená dědičnost (je něco lepšího než OOP?)

Doufám, že jste tazatelovi pomohli ...
Vzhledem k obecnosti otázky celkem jo, až na to zaplevelení diskusí o FP ve hrách.

Tak při vší úctě, relevantnější by bylo (alespoň pro mne) vyjádření tazatele.

Inkvizitor

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #303 kdy: 14. 09. 2015, 14:23:00 »
Řekněme, že chci mít objekty čtverec, obdélník, kosočtverec a rovnoběžník. Je jasné, že s jednoduchou dědičností se daleko nedostanu. Proto obecný dotaz: existuje nějaké ... ?

... Omezená dědičnost (je něco lepšího než OOP?)

Doufám, že jste tazatelovi pomohli ...
Vzhledem k obecnosti otázky celkem jo, až na to zaplevelení diskusí o FP ve hrách.

Tak při vší úctě, relevantnější by bylo (alespoň pro mne) vyjádření tazatele.

No to je právě ono - už se, pokud mi to nějak neuniklo, neozval, tudíž ten thread už dávno není jeho.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #304 kdy: 14. 09. 2015, 14:29:10 »
Jak uz od zacatku tady nekdo rikal, vsechno zavisi na zpusobu pouziti.
Tyhle zobecnovani, co tady delas zas vedou tomu, ze casto to co kompl zvladl pred 20 lety s tehdejsim hw, dela dneska na 20 let novejsim hw stejnou dobu. Kdyz budes mit miliardy ctvercu a budes je nekde muset skladovat a budes potrebovat pocitat jejich obsahy, tak si sakra rozmyslis, jestli tam budes nekde pocitat cos, drzet si zbytecne data, atp.
Já znám protokoly primárně z Haskellu. Nevím jak jinde ale v Haskellu tu potřebnou tabulku funkcí hlídá a předává překladač. A taky ty funkce ochotně inlinuje všude, kde to jenom jde. Takže pokud budu mít miliardy čtverců a budu si jistý tím že to jsou čtverce, tak mi překladač zainlinuje volání a kosinus vyoptimalizuje pryč.

Zrovna protokoly jsou abstrakce, která umí být překvapivě levná. Teda aspoň v příčetně navrženém jazyce.

Ha, tak Swift se zdá být naprosto příčetný, pro Array<Square> je zrychlení výpočtu skoro o dva řády.


noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #305 kdy: 14. 09. 2015, 14:47:25 »
Chyba v úvaze je v tom, že předpokládáš, že ten objekt něco renderuje.
Logické rozdělení je to z pohledu toho, zda se mohou elementy ovlivňovat.
Bohuzel pro rychle vytvoreni modelu (meshe) je myslim nutna tato reprezentace (ikdyz sam se nerendruje, je rendrovan). Uzivaji se co nejefektivnejsi datove typy (tusim pole id bloku - primitivnich intu; overhead pri pouziti napr. Map[(Int,Int,Int),Int] by byl primo monstrozni). Je take treba si uvedomit narocnost voxeloveho sveta - std. dohlednost je IIRC 10, tzn. 20x20chunku = 400x16^2x256 bloku = ~26 milionu bloku (kazdy blok az 6 sten ruzne textury a osvetleni). To je nutne efektivne skladovat, jinak dojde pamet velmi rychle (zanedbal jsem napr. osvetleni, sky flag, tile entity a urcite dalsi veci).

Zkus si představit jednoduché lineární pole objektů (pańáců a pomerančů). Pak můžeš mět jakýsi strom, který určuje, kde se které větve mohou ovlivňovat. Sourozence můžeš paralelizovat (když si to čtu, tak to zní děsivě, ale popisuji spíše potenciál, protože v praxi by to byl spíš takovej keř). A v každém ticku se ti v tom stromu provedou výpočty a v kořeni ti vypadne seznam všech změn, které musíš provést na scéně. Až tady máš to místo, kde budeš renderovat. A kde můžeš perfektně optimalizovat (zničení chunku, a vygenerování už finálního se všemi elementy, renderování jen viditelné scény, atd). A díky tomu, že mám seznam všech změn, mohu zkusit paralelizovat i to renderování.
Na entitach si to celkem predstavit jde (je jich pouze par, v pripade MC tak do stovky v okruhu viditelnosti), ale v pripade bloku? Mit stromy i pro bloky, napr. pro kazdy blok lavy (blok vyskytujici se v "prirode", tj. muze byt ve velkem mnozstvi soucasti sveta), ktery muze zapalit horlave objekty ve svem okoli, bude vetev v tom stromu? To bysme se posunuli o rad, mozna o dva. V kazdem ticku se muze lava "rozlit" dale (zmen za tick u lavovych jezer muze byt tedy mnoho), opravdu si nedovedu predstavit, ze by generovani toho stromu trvalo kratsi dobu, nez neparalelni puvodni verze. Kdyz vidim, jake vykonostni problemy jsou v aktualnim MC obcas s tokem vody, lavy a prepocty osvetleni (kteremu ta tvorba stromu bude asi celkem blizko), tak mi prijde, ze tohle reseni nemuze fungovat (ale mozna to jen klame, fakt nevim).

V zaveru mi z toho tedy vyplyva, ze by musela zustat stavajici reprezentace (pouzivat strom pro meshovani sveta si myslim rozumne nepujde) a paralelne udrzovat strom ovlivnitelnosti. Pomoci nej paralelizovat tick a z vysledneho seznamu zmen paralelne zpracovat vsechny chunky zaraz (prikazy pro 1 chunk tedy budou sekvencni, coz nevadi, maloktere (?) pouzivane cpu ma vice nez 400 jader). Je otazka, zda rezie spjata s udrzovanim/generovanim stromu a rozdelovanim prace (seznam zmen) nevyjde hur, nez stary jednodussi pristup ??? (tyto zmeny se budou bezne provadet klidne nekolikrat do vteriny, pokud budou trvat dele nez jeden frame, tak se hra zacne "skubat"; anebo by se muselo zacit resit nejaky "shadow world" ala "shadow dom", to ale nevim, jestli by pametove fungovalo).

Jak by se to dalo dělat lépe? JS navrhoval Monády, ale (pravděpodobně díky nedostatku zkušeností) bych se bál aby mi z toho nevylezl podobnej nepřehlednej mrdník, jaký obhajuje gamer u svého mutable řešení.
Prijde mi, ze tema programovani her je velmi narocne - musi se zajistit velmi dobry vykon, pritom ale stabilni (aby nekolisalo FPS). U voxelovych her je vse jeste umocneno nepodporou enginu i GPU. Pritom zrovna ty voxelove hry jsou myslim primo idealni pro masivni paralelizaci (a tedy i pro FP?).

Omlouvam se za dlouhy post. Doufam, ze jsem nektere veci moc nezjednodusil nebo spatne nepochopil. Jen dodam, ze jsem napsal velmi jednoduche rendrovani voxeloveho sveta v jME a od te doby jsem zacal mit respekt k Minecraftu a jeho (ne)dobremu vykonu ;D.

BoneFlute

  • *****
  • 2 046
    • Zobrazit profil
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #306 kdy: 14. 09. 2015, 15:30:30 »
Uzivaji se co nejefektivnejsi datove typy (tusim pole id bloku - primitivnich intu; overhead pri pouziti napr. Map[(Int,Int,Int),Int] by byl primo monstrozni).
Tady se moc nechytám co přesně myslíš. Navíc mám nezdravou důvěru v optimalizátor GHC :-) Asi by to chtělo konkrétní příklad.

Na entitach si to celkem predstavit jde (je jich pouze par, v pripade MC tak do stovky v okruhu viditelnosti), ale v pripade bloku? Mit stromy i pro bloky, napr. pro kazdy blok lavy (blok vyskytujici se v "prirode", tj. muze byt ve velkem mnozstvi soucasti sveta), ...
Mluvím-li o entitách, tak mluvím i o neživých věcech. Jako entitu jsem měl cokoliv, co mohlo reagovat s okolím. Aktivně, nebo jen klást odpor.

V zaveru mi z toho tedy vyplyva, ze by musela zustat stavajici reprezentace (pouzivat strom pro meshovani sveta si myslim rozumne nepujde) a paralelne udrzovat strom ovlivnitelnosti. Pomoci nej paralelizovat tick a z vysledneho seznamu zmen paralelne zpracovat vsechny chunky zaraz (prikazy pro 1 chunk tedy budou sekvencni, coz nevadi, maloktere (?) pouzivane cpu ma vice nez 400 jader). Je otazka, zda rezie spjata s udrzovanim/generovanim stromu a rozdelovanim prace (seznam zmen) nevyjde hur, nez stary jednodussi pristup ??? (tyto zmeny se budou bezne provadet klidne nekolikrat do vteriny, pokud budou trvat dele nez jeden frame, tak se hra zacne "skubat"; anebo by se muselo zacit resit nejaky "shadow world" ala "shadow dom", to ale nevim, jestli by pametove fungovalo).
Možná si jen nerozumíme, protože mi přijde, že popisuješ to co jsem měl na mysli já. Plus-mínus :-)

Ivan Nový

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #307 kdy: 14. 09. 2015, 15:48:18 »

První je analogií imperativního přístupu, pokaždé když nastavím nový stav objektu, tak vyrobím celý nový "správný" svět. To bude fungovat naprosto stejně jako imperativní přístup. Má to ale svoje ale. I kdyby výroba nového světa nestála žádný výkon navíc (čemuž nevěřím), tak je takový design silně diskutabilní. Mám prakticky netestovatelné funkce, když funkce vrací celý svět, může potenciálně změnit cokoliv. Vůbec nemám přehled o datech, která do funkcí vstupují a které funkce vrací, z interface to není vidět.

Druhý způsob je nedělat změny ve světě ihned, ale schovat si je na později. Vytvořím seznam událostí, co se má se světem stát. Problém tohoto přístupu je v tom, že dává chybné výsledky a nekonzistentní svět. Když počítám všechno z původního světa, můžou se rozhodnout panácí 1 i 2, že oba vstoupí na pole A. Teď co s tím? Nechám panáka 2 tam, kde je, nebo spustím ex-post znovu AI a najdu pro panáka 2 novou pozici? Obě řešení jsou špatná. Hráč očekává, že panák 2 něco udělá a ne že bude občas "zasekávat". Spouštět znovu AI je nekoncepční a stojí to výkon. I když jde o naprosto elemetární příklad, tak stejně nevím, co s tou kolizí udělat. V reálně hře budou tisíce různých událostí a miliony jejich možných vzájemných kombinací. Já nemám dost dobrý mozek na to, abych dokázal domyslet, jak řešit všechny možné kolize. Nevybral bych si toto řešení ani náhodou. Z mého pohledu je nedeterministické.

A víte co je zajímavé, že rálný svět vykazuje oba tyto přístupy, makrosvět je to první řešení a kvantový mikrosvět to druhé :-)

Zvolte rozsahy možných kolizí a náhodně vyberte výsledek z toho rozsahu. Logické kolize do makrosvěta hry nezasáhnou, když kolem elementárních prvků definujete okolí, kde interakce probíhají, přenos interakce pak bude možný jen tehdy, když bude existovat řetěz elementárních prvků, či událostí, které se vzájemně budou dotýkat v rámci takto definovaného okolí :-)))


Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #308 kdy: 14. 09. 2015, 15:56:28 »
...

A víte co je zajímavé, že rálný svět vykazuje oba tyto přístupy, makrosvět je to první řešení a kvantový mikrosvět to druhé :-)

Zvolte rozsahy možných kolizí a náhodně vyberte výsledek z toho rozsahu. Logické kolize do makrosvěta hry nezasáhnou, když kolem elementárních prvků definujete okolí, kde interakce probíhají, přenos interakce pak bude možný jen tehdy, když bude existovat řetěz elementárních prvků, či událostí, které se vzájemně budou dotýkat v rámci takto definovaného okolí :-)))

A o všemocném, všezachraňujícím a všeřešícím trhu nic?
Nic??
NIC???

Radek Miček

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #309 kdy: 14. 09. 2015, 16:10:46 »
Uzivaji se co nejefektivnejsi datove typy (tusim pole id bloku - primitivnich intu; overhead pri pouziti napr. Map[(Int,Int,Int),Int] by byl primo monstrozni).
Tady se moc nechytám co přesně myslíš. Navíc mám nezdravou důvěru v optimalizátor GHC :-) Asi by to chtělo konkrétní příklad.

Stačí se podívat na Computer Language Benchmarks Game. Například problém n-body je v Haskellu řešen pomocí těchto konstrukcí:

Kód: [Vybrat]
offset o = (plusPtr (castPtr p::Ptr Double)(o*8+i*64))

nebo

Kód: [Vybrat]
pa <- mallocBytes (len * sizeOf (undefined::Planet))

Naneštěstí je řešení v Haskellu delší, méně přehledné, méně bezpečné a pomalejší než řešení v Javě.

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #310 kdy: 14. 09. 2015, 16:54:16 »
Presne jak pise Radek Miček (ten typ predstavuje mapu [slovnik] ze souradnice [triple intu] na int [id bloku - napr. trava, kamen]; primitivnim intem myslim datovy typ, ktery v JVM IIRC odpovida 64b integeru, ne-primitvni by byl objekt obalujici int [v Jave Integer?]).

Problem je v tom, ze pri uvedenem prikladu s bloky se pocita doslova kazdy bit - "struktura" predstavujici blok (v nasem pripade 64b int, kde cast myslim tvori bitove flagy) - se opakuje ~20 milionkrat (a to se bavime jen o klientovi, server muze mit desitky hracu, tzn. nasobne vice prace). Implementace chunku jako Map[(Int,Int,Int),Int] by znamenala minimalne 300% pametovy overhead (explicitni souradnice) a bylo by to podstatne pomalejsi, protoze pro vyhledavani v teto strukture se budou pouzivat hashe souradnic, prestoze by to mohlo byt v klidu pole intu (mozna ne o tolik pomalejsi, jit optimalizator obcas dela zazraky; navic pri vyhledavani se bude konstruoovat triple podle ktereho se vyhledava). Muj priklad je extrem (mluvim z pohledu JVM, Haskell skoro neznam), nikdo by neco takoveho asi ani nezkousel, ale celkem dobre to ilustruje podstatu.

PS: Prace s ukazateli v Haskellu nevypada vubec vabne (pripadam si jak kdybych cetl C++ kod).

Logik

  • *****
  • 1 049
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #311 kdy: 14. 09. 2015, 17:09:04 »
kit: "Objektové jazyky na tom bývají hůř, protože když to nezvládnou zoptimalizovat při překladu, tak za běhu to už nedohoní a ten kosinus budou počítat vždy."
To bych se hádal, to jazyky s bytekódem když zjistí že je možná a vhodná "optimalizace za běhu", tak si klidně bytekód přeloží znovu pro konkrétní případ.

===

Jinak celkově debatu nechápu. Porovnávají se tu dvě řešení: s eventy a bez, a jedno z nich "se považuje" za funkcionální. Co komu brání napsat v imperativním přístupu řešení s eventy a získat tím také výhodu změn scény a tedy možnost vzniku kolizí pouze na jednom místě? IMHO ani jedno z prezentovaných řešení nijak nesouvisí s paradigmatem jazyka, v kterém ho budete implementovat.

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #312 kdy: 14. 09. 2015, 17:17:37 »
Jinak celkově debatu nechápu. Porovnávají se tu dvě řešení: s eventy a bez, a jedno z nich "se považuje" za funkcionální. Co komu brání napsat v imperativním přístupu řešení s eventy a získat tím také výhodu změn scény a tedy možnost vzniku kolizí pouze na jednom místě? IMHO ani jedno z prezentovaných řešení nijak nesouvisí s paradigmatem jazyka, v kterém ho budete implementovat.
To vzniklo tak, že gamer si myslí, že řešení s eventy je jediné možné a pořád dokola to opakoval, i když byl opakovaně upozorněn, že jediné možné není :)

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #313 kdy: 14. 09. 2015, 17:24:43 »
Jinak celkově debatu nechápu. Porovnávají se tu dvě řešení: s eventy a bez, a jedno z nich "se považuje" za funkcionální. Co komu brání napsat v imperativním přístupu řešení s eventy a získat tím také výhodu změn scény a tedy možnost vzniku kolizí pouze na jednom místě? IMHO ani jedno z prezentovaných řešení nijak nesouvisí s paradigmatem jazyka, v kterém ho budete implementovat.

To si myslim nikdo netvrdi, akorat se tak asi nedeje. Pokud jsou vhodnejsi nastroje pro implementaci daneho reseni (eventy) ve funkcionalnich jazycich, tak asi lide vice tihnout k tomu uzivat ty funkc. jazyky pro dane reseni. Priklad: pri psani utilitky v Pythonu jsem se snazil to psat funkcionalne, ale prestoze to jde, tak je to tak krkolomne a neuveritelne uzvanene... Napr. na Scalu [nebo nedej boze Haskell] to proste nema.

No, rekl bych, ze ta druha moznost - mutable data ve funkcionalnim jazyku - nebude moc typicka :D.

PS: Jak pise pan Prymek, neni to jedine reseni. Napr. Akka (knihovna s actory) je dostupna i pro Javu, ktera neni urcite funkcionalni jazyk.

Inkvizitor

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #314 kdy: 14. 09. 2015, 18:09:04 »
Uzivaji se co nejefektivnejsi datove typy (tusim pole id bloku - primitivnich intu; overhead pri pouziti napr. Map[(Int,Int,Int),Int] by byl primo monstrozni).
Tady se moc nechytám co přesně myslíš. Navíc mám nezdravou důvěru v optimalizátor GHC :-) Asi by to chtělo konkrétní příklad.

Stačí se podívat na Computer Language Benchmarks Game. Například problém n-body je v Haskellu řešen pomocí těchto konstrukcí:

Kód: [Vybrat]
offset o = (plusPtr (castPtr p::Ptr Double)(o*8+i*64))

nebo

Kód: [Vybrat]
pa <- mallocBytes (len * sizeOf (undefined::Planet))

Naneštěstí je řešení v Haskellu delší, méně přehledné, méně bezpečné a pomalejší než řešení v Javě.

Nevím, jestli by to v tomto konkrétním případě měnilo situaci, ale vybrat jeden konkrétní algoritmus původně použitý v Javě a pak chtít po implementátorech ve všech možných i nemožných jazycích ten algoritmus používat mi přijde zrovna třeba pro funkcionální jazyky jako dost velký podraz.