Paměťová a výpočetní náročnost JVM vs .NET

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #90 kdy: 18. 09. 2016, 13:28:57 »
Když dojde k normálnímu ukončení, tak aplikace dostane zprávu předem - tj. data může uložit.
A když dojde k nenormálnímu ukončení, tak o ta data přijdeme.

Neuložení dat však příliš nevadí - při nejhorším nějakým uživatelům ukážeme nějaké produkty vícekrát, než chceme.
Asi nebudete ta data pro tisíce uživatelů držet trvale v paměti, ostatně někdy bude potřeba tu aplikaci restartovat. Takže je stejně nějak ukládat musíte. Pak je ale mnohem jednodušší ukládat je průběžně a počítat s uloženými daty, než je kešovat na straně webového serveru a řešit invalidaci keše a ukládání atd.

Nemusí být pravda - zvláště na sdíleném hostingu, kde je databáze vytížená. Krom toho, když neposíláte do databáze vše ihned, nějaký provoz po síti ušetříte.
Když je databáze vytížená, rozhodně jí nepomůžete tím, že jí budete nutit číst z disku zbytečná data a odesílat je po síti.

Máme to takto implementované a odpověď z databáze trvá méně než 10 ms (tj. nemůžeme ušetřit desítky nebo stovky ms).
Co jste s těmi daty dělali, že vám jejich zpracování procesorem trvalo déle než 10 ms?


Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #91 kdy: 18. 09. 2016, 13:29:55 »
Obzvláště použití streamů na běžné pořád opakované úkony kód zkracuje a zpřehledňuje. Pokud to interně v JVM pojede jako pole intu, jedině dobře.
Myslíte rozhraní java.util.stream.IntStream?

Pokud stream používáte uvnitř generické třídy, tak tak musíte specializovat i tuto generickou třídu. Navrhujete tedy místo jedné generické třídy napsat ještě třídu pro každý generický typ?

Pokud je navíc generická třída parametrizována více typy, musíte specializaci provést pro každou jejich kombinaci. I kdybyste to dokázal, tak skončíte s tisíci tříd, přičemž většina z nich bude nepoužitých. Pro .NET se o toto stará JIT, který vygeneruje kód jen pro používané specializace.


Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #92 kdy: 18. 09. 2016, 13:34:33 »
Když dojde k normálnímu ukončení, tak aplikace dostane zprávu předem - tj. data může uložit.
A když dojde k nenormálnímu ukončení, tak o ta data přijdeme.

Přesně tak - nevadí to, jak jsem již vysvětlil.

Citace
Neuložení dat však příliš nevadí - při nejhorším nějakým uživatelům ukážeme nějaké produkty vícekrát, než chceme.
Asi nebudete ta data pro tisíce uživatelů držet trvale v paměti, ostatně někdy bude potřeba tu aplikaci restartovat. Takže je stejně nějak ukládat musíte. Pak je ale mnohem jednodušší ukládat je průběžně a počítat s uloženými daty, než je kešovat na straně webového serveru a řešit invalidaci keše a ukládání atd.

Jednodušší to je, rychlejší už to být nemusí.

Citace
Nemusí být pravda - zvláště na sdíleném hostingu, kde je databáze vytížená. Krom toho, když neposíláte do databáze vše ihned, nějaký provoz po síti ušetříte.
Když je databáze vytížená, rozhodně jí nepomůžete tím, že jí budete nutit číst z disku zbytečná data a odesílat je po síti.

Já ji vytěžuji méně, jak jsem již psal výše (např. díky cachování).

Citace
Máme to takto implementované a odpověď z databáze trvá méně než 10 ms (tj. nemůžeme ušetřit desítky nebo stovky ms).
Co jste s těmi daty dělali, že vám jejich zpracování procesorem trvalo déle než 10 ms?

Nic takového jsem nepsal a ani to nejde odvodit z toho, co jsem psal.

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #93 kdy: 18. 09. 2016, 16:31:16 »
Co jste s těmi daty dělali, že vám jejich zpracování procesorem trvalo déle než 10 ms?

Nic takového jsem nepsal a ani to nejde odvodit z toho, co jsem psal.
Když čekáte na odpověď z databáze 10 ms, máte 10 ms času procesorového času, kdy může procesor místo čekání provádět ty vaše výpočty. Není žádný důvod to urychlovat pod 10 ms, protože pak stejně bude muset čekat na tu databázi. Takže vám to před optimalizací muselo trvat zřetelně déle, než 10 ms.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #94 kdy: 18. 09. 2016, 17:10:21 »
Co jste s těmi daty dělali, že vám jejich zpracování procesorem trvalo déle než 10 ms?

Nic takového jsem nepsal a ani to nejde odvodit z toho, co jsem psal.
Když čekáte na odpověď z databáze 10 ms

Psal jsem, že čekáme méně než 10 ms.


Martin

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #95 kdy: 19. 09. 2016, 00:24:32 »
A těch méně než 10 ms bylo docíleno optimalizacemi zaměřenými na cache?

Radek Miček

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #96 kdy: 19. 09. 2016, 07:27:51 »
A těch méně než 10 ms bylo docíleno optimalizacemi zaměřenými na cache?

Ne, těch 10 ms vůbec nesouvisí s původní diskuzí. K tomuto OT jsme se dostali, když jsem uvedl praktický (a zároveň i hezký) příklad, kdy se ve webové aplikaci může objevit seznam dvojic (a v C# tento seznam může zabrat méně paměti a méně alokací než v Javě - díky uživ. definovaným hodnotovým typům a specializaci generik).

Ale ještě důležitější příklad automatické specializace generik jsem zmínil teprve o pár komentářů výše:

Myslíte rozhraní java.util.stream.IntStream?

Pokud stream používáte uvnitř generické třídy, tak tak musíte specializovat i tuto generickou třídu. Navrhujete tedy místo jedné generické třídy napsat ještě třídu pro každý generický typ?

Pokud je navíc generická třída parametrizována více typy, musíte specializaci provést pro každou jejich kombinaci. I kdybyste to dokázal, tak skončíte s tisíci tříd, přičemž většina z nich bude nepoužitých. Pro .NET se o toto stará JIT, který vygeneruje kód jen pro používané specializace.

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #97 kdy: 19. 09. 2016, 08:16:04 »
Ne, těch 10 ms vůbec nesouvisí s původní diskuzí. K tomuto OT jsme se dostali, když jsem uvedl praktický (a zároveň i hezký) příklad, kdy se ve webové aplikaci může objevit seznam dvojic
Těch 10 ms samozřejmě s původní diskusí souvisí. Protože jste to uváděl jako příklad, kdy úprava aplikace, aby lépe zacházela s procesorovou keší, zrychlí práci aplikace. Vzhledem k tomu, že ta aplikace méně než deset ms čeká na data z DB, může po těch méně než 10 ms provádět libovolné výpočty a nijak ji to nezpomalí. Takže před tou optimalizací vám to asi muselo trvat déle než méně než 10 ms, jinak by ta optimalizace byla zbytečná.

v C# tento seznam může zabrat méně paměti a méně alokací než v Javě - díky uživ. definovaným hodnotovým typům a specializaci generik
Evidentně stále nechápete, že to není záležitost programovacího jazyka, ale toho, jak to programátor napíše.

Jinak když už byste chtěl nějaký kód optimalizovat pro použití CPU cache, měl byste si zaktualizovat informace o tom, jak dnešní CPU fungují – od dob Pentií se to přeci jen trochu posunulo. Dnešní procesory už neprovádějí jednu operaci za druhou, ale snaží se provádění paralelizovat (provádění těch instrukcí, které běží v jednom vlákně – z hlediska programátora je to transparentní a ten paralelní postup musí dát přesně stejný výsledek, jako kdyby se to provádělo klasicky instrukce po instrukci). A mezi ty paralelní operace patří i získávání dat z hlavní paměti – takže to, že se na nějaká data odkazuje referencí, nemusí být pro procesor žádná tragédie. Naopak programátor, který se snaží něco optimalizovat ručně, může učinit kód pro procesor tak nepřehledný, že bude jeho spekulativní provádění kódu k ničemu a dotyčná optimalizace efektivně zpomalí provádění kódu na sériové provádění instrukcí.

Fbi

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #98 kdy: 19. 09. 2016, 09:07:24 »
Dnešní procesory už neprovádějí jednu operaci za druhou, ale snaží se provádění paralelizovat (provádění těch instrukcí, které běží v jednom vlákně – z hlediska programátora je to transparentní a ten paralelní postup musí dát přesně stejný výsledek, jako kdyby se to provádělo klasicky instrukce po instrukci)

Použít slovo paralelizovat není úplně přesné. Instrukce se provádí out-of-order, což znamená že se mohou provádět v jiném pořadí, než po sobě jdou v programu. Například když CPU čeká na nějaká data z paměti, tak může provádět jinou instrukci.

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #99 kdy: 19. 09. 2016, 09:33:52 »
Použít slovo paralelizovat není úplně přesné. Instrukce se provádí out-of-order, což znamená že se mohou provádět v jiném pořadí, než po sobě jdou v programu. Například když CPU čeká na nějaká data z paměti, tak může provádět jinou instrukci.
Ano, ale v jednom taktu může procesor provést i několik instrukcí, což bych zjednodušeně nazval paralelizací. Těch optimalizací, které provádějí moderní procesory, je celá řada, a myslím, že v tomhle vlákně nemá smysl je probírat.

N

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #100 kdy: 19. 09. 2016, 09:42:32 »
Ty vypocty sedi, ale otazka zni, proc je pouzit ArrayList? Docela bych rekl, ze je to dost umely priklad ne? Pole intu neni v mode? Btw i kdyby znela odpoved "ale ja potrebuju insert/delete/append", tak v ArrayListu se budou delat  ty same operace, co by se udelaly s arraycopy.

S kolekcemi (interně primárně arraylisty) se  pracuje velice pohodlně, rychle a hlavně bezpečně. Obzvláště použití streamů na běžné pořád opakované úkony kód zkracuje a zpřehledňuje. Pokud to interně v JVM pojede jako pole intu, jedině dobře.

Naopak arraylisty jsou docela napytel, protoze boxujou vsechny data. Prace s tim je pomala... lepsi tp uz nebude,protoze java ma posrane generika.

dustin

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #101 kdy: 19. 09. 2016, 13:27:05 »
Naopak arraylisty jsou docela napytel, protoze boxujou vsechny data. Prace s tim je pomala... lepsi tp uz nebude,protoze java ma posrane generika.

A právě proto tu celou dobu mluvíme o hodnotových typech, které se pro javu připravují

gl

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #102 kdy: 19. 09. 2016, 13:36:43 »
A mezi ty paralelní operace patří i získávání dat z hlavní paměti – takže to, že se na nějaká data odkazuje referencí, nemusí být pro procesor žádná tragédie. Naopak programátor, který se snaží něco optimalizovat ručně, může učinit kód pro procesor tak nepřehledný, že bude jeho spekulativní provádění kódu k ničemu a dotyčná optimalizace efektivně zpomalí provádění kódu na sériové provádění instrukcí.

Zkus si porovnat rychlost průchodu dlouhého pole.

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #103 kdy: 19. 09. 2016, 18:38:10 »
Zkus si porovnat rychlost průchodu dlouhého pole.
Porovnat s čím? A co znamená „průchod pole“?

Radek Miček

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #104 kdy: 19. 09. 2016, 20:36:40 »
Ne, těch 10 ms vůbec nesouvisí s původní diskuzí. K tomuto OT jsme se dostali, když jsem uvedl praktický (a zároveň i hezký) příklad, kdy se ve webové aplikaci může objevit seznam dvojic
Vzhledem k tomu, že ta aplikace méně než deset ms čeká na data z DB, může po těch méně než 10 ms provádět libovolné výpočty a nijak ji to nezpomalí.

Ta aplikace potřebuje provádět výpočty s těmi daty z DB - nemůže provádět žádné užitečné výpočty bez těch dat.

Citace
takže to, že se na nějaká data odkazuje referencí, nemusí být pro procesor žádná tragédie.

Celé to může být pomalejší několikanásobně - v nejhorším případě (objekty, na něž reference v poli ukazují, jsou rozházeny náhodně v paměti) klidně i 20x.

Podívejte se třeba, jak pomáhá Miniboxing ve Scale. Nebo na to, jaký je rozdíl, když se data v poli čtou v náhodném pořadí nebo postupně od začátku do konce (30. minuta).

Citace
Naopak programátor, který se snaží něco optimalizovat ručně, může učinit kód pro procesor tak nepřehledný

My se ale nebavíme o žádné složité optimalizaci - naopak pro procesor dojde ke zjednodušení (ubyde dereferencování) a pro programátora se buď nic nezmění nebo se jen nahradí klíčové slovo class klíčovým slovem struct.

V Javě takové jednoduché optimalizace nejde udělat buď vůbec nebo pomocí duplikace kódu.