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

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #15 kdy: 16. 09. 2016, 20:00:17 »
Asi nejde o paměťové nároky, ale o lokálnost. Jak se dá například v Javě vytvořit pole objektů, tak aby bylo zaručeno, že jsou v paměti za sebou?
Netuším, jak by to, zda pole objektů je nebo není v paměti za sebou, mohlo způsobit, že bude Java hosting náročnější na zdroje a webhosterovi se nevyplatí.

A jinak pole objektů, které budou v paměti za sebou, se v Javě vytvoří tak, že se vytvoří pole objektů.

Kód: [Vybrat]
Object[] poleObjektu = new Object[x];


javaman ((

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #16 kdy: 16. 09. 2016, 20:18:42 »
Na masivní degradaci výkonu stačí i kolekce obsahující pouhé tisíce prvků. Přístup Javy totiž mrhá cachí a komplikuje práci prefetcheru.
Napsat špatný program lze v jakémkoli jazyce. Pokaždé přijdete s něčím novým, nicméně ještě jste nepřišel s ničím, co by dokazovalo vaše původní tvrzení, že absence uživatelských hodnotových typů v Javě způsobuje výrazně větší paměťové nároky Java aplikací.


Asi nejde o paměťové nároky, ale o lokálnost. Jak se dá například v Javě vytvořit pole objektů, tak aby bylo zaručeno, že jsou v paměti za sebou?


K čemu by takový nesmysl byl?


Asi nejde o paměťové nároky, ale o lokálnost. Jak se dá například v Javě vytvořit pole objektů, tak aby bylo zaručeno, že jsou v paměti za sebou?
Netuším, jak by to, zda pole objektů je nebo není v paměti za sebou, mohlo způsobit, že bude Java hosting náročnější na zdroje a webhosterovi se nevyplatí.

A jinak pole objektů, které budou v paměti za sebou, se v Javě vytvoří tak, že se vytvoří pole objektů.

Kód: [Vybrat]
Object[] poleObjektu = new Object[x];

To je pole referencí, ne?

gl

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #17 kdy: 16. 09. 2016, 20:23:12 »
K čemu by takový nesmysl byl?

Efektivnější využití procesorové cache?

gl

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #18 kdy: 16. 09. 2016, 20:32:54 »
Asi nejde o paměťové nároky, ale o lokálnost. Jak se dá například v Javě vytvořit pole objektů, tak aby bylo zaručeno, že jsou v paměti za sebou?
Netuším, jak by to, zda pole objektů je nebo není v paměti za sebou, mohlo způsobit, že bude Java hosting náročnější na zdroje a webhosterovi se nevyplatí.

A jinak pole objektů, které budou v paměti za sebou, se v Javě vytvoří tak, že se vytvoří pole objektů.

Kód: [Vybrat]
Object[] poleObjektu = new Object[x];

Nemusí se to pole potom ještě projít a zavolat pro každý objekt konstruktor? I kdyby se ty objekty vytvořily za sebou, pořád budou v paměti jinde než to pole. Možná budou blízko a možná to nevadí. Javu moc neznám, ale v C bych pole ukazatelů nepoužil, pokud by šlo o výkon.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #19 kdy: 16. 09. 2016, 20:39:02 »
Citace
Myslím, že ASP.NET MVC podporuje drtivá většina webhostingů - tj. myslím si, že téměř všechny webhostingy to zvládnou.
Takže můžu vzít libovolnou aplikaci napsanou v C# využívající ASP.NET MVC a libovolné další .NET knihovny (třeba iTextSharp , Saxon EE .NET) a nasadit ji na kterýkoli hosting, který podporuje ASPX, třeba Active24, ASPone, web4u?

Ano, to by mělo fungovat bez problémů - nicméně zmíněné knihovny neznám. Obecně je dobré vybírat hosting, který má nastaven full trust, což třeba ASPone má (u ostatních nevím, nicméně většina hostingů povoluje právě full trust od ASP.NET 4 a výš).


javaman ((

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #20 kdy: 16. 09. 2016, 20:43:06 »
K čemu by takový nesmysl byl?

Efektivnější využití procesorové cache?

To jsi na úrovni optimalizací, které tě až tak netrápí. Hlavně ta dnešní logika cache bude asi dost složitá.

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #21 kdy: 16. 09. 2016, 20:49:22 »
To je pole referencí, ne?
V Javě je to pole objektů, Java nerozlišuje objekt a referenci.

Efektivnější využití procesorové cache?
Pokud mám problém s využitím procesorové cache, budu řešit efektivnější využití procesorové cache, a ne vytváření pole objektů tak, aby všechny objekty byly v paměti za sebou (už jenom proto, že do té cache se moc objektů nevejde).

Ale hlavně to nijak nesouvisí s dotazem, protože webhoster neovlivní, jak bude nějaká aplikace zacházet s cache procesoru, ať ta aplikace bude napsaná v čemkoli.

Nemusí se to pole potom ještě projít a zavolat pro každý objekt konstruktor? I kdyby se ty objekty vytvořily za sebou, pořád budou v paměti jinde než to pole.
Ano, ale tohle je v Javě pole objektů. V Javě jako jazyku se umístění v paměti neřeší, protože paměť z Javy nevidíte.

Možná budou blízko a možná to nevadí.
V drtivé většině případů to nevadí.

Javu moc neznám, ale v C bych pole ukazatelů nepoužil, pokud by šlo o výkon.
Pokud by šlo o výkon, pole nepoužil bych v Javě pole objektů. Pokud bych zjistil, že v konkrétní implementaci kompilátoru a JVM je problém s procesorovou cache, řešil bych ten konkrétní problém – například s využitím toho, jak jsou v paměti uloženy fieldy objektu.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #22 kdy: 16. 09. 2016, 21:05:40 »
Na masivní degradaci výkonu stačí i kolekce obsahující pouhé tisíce prvků. Přístup Javy totiž mrhá cachí a komplikuje práci prefetcheru.
Napsat špatný program lze v jakémkoli jazyce. Pokaždé přijdete s něčím novým, nicméně ještě jste nepřišel s ničím, co by dokazovalo vaše původní tvrzení, že absence uživatelských hodnotových typů v Javě způsobuje výrazně větší paměťové nároky Java aplikací.

Jak už jsem se opravil, měl jsem na mysli absenci uživatelsky def. hodnotových typů + specializace.

Příkladem je seznam čísel, když v Javě použijete generický ArrayList pro uložení 1000 intů. Předpokládejme, že aplikace běží nad HotSpotem a na 64 bitové architektuře. Pro takový seznam se alokuje minimálně 1002 objektů. Každý objekt obsahuje hlavičku (mark word 8 bajtů + klass pointer 8 bajtů; dohromady 16 bajtů). Instance ArrayList se bude skládat z hlavičky, pole, jenž obsahuje minimálně 1000 referencí, a nějakých dalších dat (minimálně 16 bajtů (hlavička) + 8 bajtů (reference na pole) + 8016 bajtů (pole referencí + hlavička) + velikost dalších dat). Pro každý int se vytvoří objekt, který AFAIK zabere min. 20 bajtů (nevím, zda JVM má nějakou minimální velikost objektů; pokud ano, může to být více). Tj. dohromady to zabere minimálně 8040 + 20 * 1000 = 28032 bajtů.

Analogická věc v .NET Core zabere zhruba 4032 bajtů + velikost dalších dat ve třídě List. Na rozdíl od Javy, kde se alokovalo 1002 objektů se zde alokují pouze 2 objekty (instance generické třídy List a pole).

Výše jsou uvedeny pouze odhady, které vycházejí z aktulních implementací - do budoucna se to může měnit.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #23 kdy: 16. 09. 2016, 21:10:50 »
Analogická věc v .NET Core zabere zhruba 4032 bajtů + velikost dalších dat ve třídě List.

Oprava: 4040 bajtů (zapomněl jsem na ukazatel na pole).

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #24 kdy: 16. 09. 2016, 21:36:00 »
Jak už jsem se opravil, měl jsem na mysli absenci uživatelsky def. hodnotových typů + specializace.

Příkladem je seznam čísel, když v Javě použijete generický ArrayList pro uložení 1000 intů. Předpokládejme, že aplikace běží nad HotSpotem a na 64 bitové architektuře. Pro takový seznam se alokuje minimálně 1002 objektů. Každý objekt

Analogická věc v .NET Core zabere zhruba 4032 bajtů + velikost dalších dat ve třídě List. Na rozdíl od Javy, kde se alokovalo 1002 objektů se zde alokují pouze 2 objekty (instance generické třídy List a pole).

Struktury v C# jsou pěkné a občas můžou pomoct, kromě toho, že samozřejmě mají své negativní stránky. Hlavní problém je ale v tom, že jejich využití v nějakých větších blocích či datových strukturách je natolik minoritní, že v zásadě nemají na typickou aplikaci významný vliv. Běžně to bývají spíš hodně low-level věci, které se stejně napíšou externě v low level jazyce C, C++ či dokonce platform specifc (ať už C s nějakýma SSE builtins nebo rovnou assembler) - typicky kryptování, maticové operace atd.

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #25 kdy: 16. 09. 2016, 21:46:36 »
Příkladem je seznam čísel, když v Javě použijete generický ArrayList pro uložení 1000 intů.
Jak už jsem psal, napsat špatný program lze v libovolném jazyce.

Analogická věc v .NET Core zabere zhruba 4032 bajtů
Ne, to není analogická věc. Analogická věc k tomu příkladu z .NET by bylo v Javě použití třídy třeba jodd.util.collection.IntArrayList, com.google.common.primitives.Ints.IntArrayAsList nebo podobné (nějakou takovou má každá knihovna s utilitami).

Radek Miček

Re:Paměťová a výpočetní náročnost JVM vs .NET
« Odpověď #26 kdy: 16. 09. 2016, 21:54:02 »
Jak už jsem se opravil, měl jsem na mysli absenci uživatelsky def. hodnotových typů + specializace.

Příkladem je seznam čísel, když v Javě použijete generický ArrayList pro uložení 1000 intů. Předpokládejme, že aplikace běží nad HotSpotem a na 64 bitové architektuře. Pro takový seznam se alokuje minimálně 1002 objektů. Každý objekt

Analogická věc v .NET Core zabere zhruba 4032 bajtů + velikost dalších dat ve třídě List. Na rozdíl od Javy, kde se alokovalo 1002 objektů se zde alokují pouze 2 objekty (instance generické třídy List a pole).

Hlavní problém je ale v tom, že jejich využití v nějakých větších blocích či datových strukturách je natolik minoritní, že v zásadě nemají na typickou aplikaci významný vliv.

Struktury se v C# používají pro newtype (např. můžeme zabalit decimal do struktury Salary, jejíž instance budou reprezentovat plat; nebo např. různá id typu int můžeme zabalit do různých struktur, díky čemuž kompilátor zajistí, že např. nezaměníme id uživatele s id skupiny), dvojice (např. když funkce vrací více hodnot a nechceme použít out parametr a ani nechceme alokovat na heapu), nullable typy.

Je pravdou, že v tom svém příkladu jsem struktur nevyužil - využil jsem specializace generik.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #27 kdy: 16. 09. 2016, 22:05:26 »
Příkladem je seznam čísel, když v Javě použijete generický ArrayList pro uložení 1000 intů.
Jak už jsem psal, napsat špatný program lze v libovolném jazyce.

Analogická věc v .NET Core zabere zhruba 4032 bajtů
Ne, to není analogická věc. Analogická věc k tomu příkladu z .NET by bylo v Javě použití třídy třeba jodd.util.collection.IntArrayList, com.google.common.primitives.Ints.IntArrayAsList nebo podobné (nějakou takovou má každá knihovna s utilitami).


Analogické je to tím, že jsem použil třídu ze standardní knihovny. Java bohužel nemá lepší třídu ve standardní knihovně. Další potíž je, že knihovna Jodd vám nepomůže, když napíšete

Kód: [Vybrat]
class Salary {
  double x;
}

To si budete muset napsat vlastní kolekci. A když pak napíšete

Kód: [Vybrat]
class UserId {
  int x;
}

tak si budete muset napsat zase další kolekci. Podobně pro dvojice (int, int), (int, bool), (bool, int), ..., trojice, ... Přičemž v C# si vystačím s kolekcí ze standardní knihovny a tím, že použiji struct místo class.

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #28 kdy: 16. 09. 2016, 22:17:03 »
Java bohužel nemá lepší třídu ve standardní knihovně.
V Javě není žádný problém s používáním knihoven. Omezovat se jen na standardní knihovnu je nesmysl.

Radek Miček

Re:Pametova a vypocetni narocnost JVM vs .NET
« Odpověď #29 kdy: 16. 09. 2016, 22:33:45 »
Java bohužel nemá lepší třídu ve standardní knihovně.
V Javě není žádný problém s používáním knihoven. Omezovat se jen na standardní knihovnu je nesmysl.

Ano, potíž je ovšem v tom, že pro dvojici (int, bool) nebo (UserId, Salary) už žádnou knihovnu nenajdete - to si budete muset napsat kolekci sám (a i tak budete zbytečně alokovat na heapu UserId a Salary).