Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Ferda Mravenec 16. 09. 2016, 08:11:05

Název: Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Ferda Mravenec 16. 09. 2016, 08:11:05
Dobry den vespolek,

 umel by tady nekdo porovnat narocnost webove aplikace v .NET a v Jave? Jde mi o hosting, je problem sehnat Javovsky hosting v nejake nizsi cene, .NET jde sehnat relativne snaz - tipnu si ze nebude tak narocny na zdroje jako Java. Pravda?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 16. 09. 2016, 08:46:14
Nepravda. Už jenom pro to, že pro .NET potřebujete Windows. Java není out-of-box pro sdílený hosting navržená, takže si hoster musí udělat vlastní řešení. Navíc o takové řešení má málokdo zájem, protože pro menší věci použije Google App Engine, Heroku a podobné, pro větší věci použijí VPS nebo vlastní hardware. Takže o sdílený hosting na Javě (předpokládám, že myslíte hostování WAR) by byl malý zájem – takže zároveň není kam rozpustit fixní náklady, tedy to nebude levné, a o to menší zájem by o to byl.

Pro obecný .NET nějaký takový existuje? Jsou sdílené webhostingy pro ASPX, ale to je podobné, jako PHP. A pak to jsou různé VPS nebo cloudová řešení jako Azure.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Ivan Nový 16. 09. 2016, 08:51:11
Nepravda. Už jenom pro to, že pro .NET potřebujete Windows. Java není out-of-box pro sdílený hosting navržená, takže si hoster musí udělat vlastní řešení. Navíc o takové řešení má málokdo zájem, protože pro menší věci použije Google App Engine, Heroku a podobné, pro větší věci použijí VPS nebo vlastní hardware. Takže o sdílený hosting na Javě (předpokládám, že myslíte hostování WAR) by byl malý zájem – takže zároveň není kam rozpustit fixní náklady, tedy to nebude levné, a o to menší zájem by o to byl.

Pro obecný .NET nějaký takový existuje? Jsou sdílené webhostingy pro ASPX, ale to je podobné, jako PHP. A pak to jsou různé VPS nebo cloudová řešení jako Azure.
VPS nemusí být drahá ceny od 100Kč měsíčně. 1GB memory, 20GB data, 1 procesor
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: lojzik 16. 09. 2016, 09:43:50
Nepravda. Už jenom pro to, že pro .NET potřebujete Windows.
Neni tak úplně pravda. Záleží co bude chtít v tom .NET dělat, jestli to bude kompatibilní mono nebo to bude udělaný na .net core, tam má ms i kontejnery pro docker
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: rv 16. 09. 2016, 09:44:25
Citace
pro .NET potřebujete Windows
Neni pravda - zkousel jsem http://www.mono-project.com/docs/web/aspnet/ (http://www.mono-project.com/docs/web/aspnet/) a funguje. Problem je, ze nenajdes hosting, ktery by ti dal asp.net na linuxu = levnejsi nez na Windows server. "Mono" se snazi, ale jsou veci, ktere pod nim nejdou a v tu chvili by ti nemohl poskytovatel takoveho hostingu (linux + .net) pomoct. Leda nabidkou na Windows ;)
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: alfonzo 16. 09. 2016, 09:44:42
java je pomalsia ako .NET. o .NET Core ani nehovorim, na ten sa java nechyta :)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: andy 16. 09. 2016, 10:04:13
Java je rychlejsia ako .net ale zere pamat, nabobtnava jej heap. Da sa to potunit parametrami VM, ale na .net core to v tomto ohlade nema. Skusal som rozne OS webove aplikacie a .net je z nejakeho dovodu proste uspornejsi. Problem je, ze zatial nie su seriozne .net core apky a casto vyzaduju iis.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 16. 09. 2016, 13:32:46
Nepravda. Už jenom pro to, že pro .NET potřebujete Windows.

Není pravda, že potřebujete Windows.

Kromě toho aplikace pro .NET Framework mohou být méně náročné na paměť díky hodnotovým typům, které pod JVM neexistují.

Citace
Pro obecný .NET nějaký takový existuje?

Co je to obecný .NET?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: perceptron 16. 09. 2016, 14:54:48
Citace
tipnu si ze nebude tak narocny na zdroje jako Java
lebo neviete robit v jave zdielany hosting. nepustite si vedla seba 10 tomcatov ak bezna appka potrebuje 256 MB, nemate na to manazment.

na to ale vsetci serou

pri dobrom projekte zarobite za 5 minut na vpsku / normalny cloud

a ak ste na vps / normalnou cloude tak ste na linuxe a date si javu zadara a bez problemov
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 16. 09. 2016, 15:42:19
Není pravda, že potřebujete Windows.
Kolik asi bude uživatelů, kteří chtějí spouštět webové aplikace na omezené verzi Mono pod Linuxem? A kolik z nich bude chtít sdílený webhosting?

Kromě toho aplikace pro .NET Framework mohou být méně náročné na paměť díky hodnotovým typům, které pod JVM neexistují.
Za prvé tohle na paměťové náročnosti aplikace vůbec nepoznáte, za druhé Java hodnotové typy má.

Co je to obecný .NET?
Obecný .NET je aplikace napsaná v kterémkoli jazyce pro .NET, třeba v C#. Předpokládám, že takovou aplikaci si na běžném sdíleném ASPX hostingu nespustím.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 16. 09. 2016, 16:14:17
Není pravda, že potřebujete Windows.
Kolik asi bude uživatelů, kteří chtějí spouštět webové aplikace na omezené verzi Mono pod Linuxem?

Řekl bych, že celkem dost programátorů používá Mono na Mac OS X pro vývoj. A kromě Mona tu je .NET Core.

BTW pro webové aplikace nebývají omezení Mona problém.

Citace
Kromě toho aplikace pro .NET Framework mohou být méně náročné na paměť díky hodnotovým typům, které pod JVM neexistují.
Za prvé tohle na paměťové náročnosti aplikace vůbec nepoznáte, za druhé Java hodnotové typy má.

Ano, máte pravdu - měl jsem napsat, že nemá uživatelsky definované hodnotové typy a specializaci (tu musíte v Javě udělat ručně - tj. zduplikovat kód pro každý primitivní typ).

Oboje se pak značně projeví ve chvíli, kdy máte mnoho instancí - například v kolekcích. Některá JVM dělají escape analysis + alokaci na zásobníku, ale to nemusí fungovat tak spolehlivě, jako uživatelsky definované hodnotové typy + specializace (proto to chtějí přidat v Javě 10, ne?).

Citace
Co je to obecný .NET?
Obecný .NET je aplikace napsaná v kterémkoli jazyce pro .NET, třeba v C#. Předpokládám, že takovou aplikaci si na běžném sdíleném ASPX hostingu nespustím.

Webové aplikace se normálně píší v C#. Například, když použijete ASP.NET MVC, tak vaše aplikace nemusí mít ani jeden ASPX soubor.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 16. 09. 2016, 16:48:45
Oboje se pak značně projeví ve chvíli, kdy máte mnoho instancí - například v kolekcích.
Nemyslím si, že by webová aplikace, která má v kolekcích uloženy stovky MB dat, byla typická.

Webové aplikace se normálně píší v C#. Například, když použijete ASP.NET MVC, tak vaše aplikace nemusí mít ani jeden ASPX soubor.
Právě proto jsem se ptal na ty webhostingy, které umí hostovat webové aplikace napsané v C#. Protože to je to, co tu porovnáváme.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 16. 09. 2016, 17:37:57
Oboje se pak značně projeví ve chvíli, kdy máte mnoho instancí - například v kolekcích.
Nemyslím si, že by webová aplikace, která má v kolekcích uloženy stovky MB dat, byla typická.

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.

Citace
Webové aplikace se normálně píší v C#. Například, když použijete ASP.NET MVC, tak vaše aplikace nemusí mít ani jeden ASPX soubor.
Právě proto jsem se ptal na ty webhostingy, které umí hostovat webové aplikace napsané v C#. Protože to je to, co tu porovnáváme.

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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 16. 09. 2016, 18:39: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í.

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?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: gl 16. 09. 2016, 19:41:44
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?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 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];
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 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?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 16. 09. 2016, 20:23:12
K čemu by takový nesmysl byl?

Efektivnější využití procesorové cache?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: gl 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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ýš).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 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á.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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).
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: kvr kvr 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 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).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: dustin 16. 09. 2016, 22:44:18
Jo, hodnotové typy by se hodily, o tom žádná. Pár let to bohužel ještě potrvá (java 10?), ale dělá se na nich.

Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 00:24:05
To jsi na úrovni optimalizací, které tě až tak netrápí. Hlavně ta dnešní logika cache bude asi dost složitá.
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).

Teda pánové. Já věděl, že je to s Javisty špatné, ale až takhle? To nevíte ani to, že přečtení pointeru tahá do cache 64B(8X tolik)? A že ta nejdůležitější a nejzákladnější zásada pro efektivní využití cache je naskládat objekty za sebe a neskákat zbytečně po pointerech?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Kolemjdoucí 17. 09. 2016, 00:27:22
To je pole referencí, ne?
V Javě je to pole objektů, Java nerozlišuje objekt a referenci.

Je to pole referencí a kdo bude tvrdit něco jiného tak ukazuje že Javě naprosto nerozumí! Objekty v Javě vznikají výhradně zavoláním konstruktoru (ať už pomocí new nebo reflexí) a reference na ně je možno přiřadit do libovolného prvku v tom poli (klidně i do více prvků tu samou referenci), nad tím kde v paměti JVM ty objekty naalokuje ale programátor v Javě nemá kontrolu.

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).

Ono ale při problémech s využitím procesorové cache je naprosto zásadní jak jsou data v paměti uložena! A co se týká velikostí cache dnešních CPU tak si aktualizujte znalosti, vejde se toho do nich docela dost.

Naimplementujte si třeba velkou matici intů v jednorozměrném poli (kde budou všechny řádky uložené jeden za druhým) a pak si změřte kolik trvá když budete procházet prvky po řádcích a kolik po sloupcích. Když budete přistupovat do toho pole postupně (aby zabírala cache) bude to mnohem rychlejší než když v něm budete skákat tak že každý další přístup znemožní použití aktuálního obsahu cache. Srovnejte to třeba i s maticí intů implementovanou jako pole polí - tam nebudete mít v Javě kontrolu nad tím kde se jednotlivá pole v paměti naalokují a zase bude výkon nižší než při sekvenčním procházení jednoho velkého pole. Přemýšlet o cache se dnes prostě z hlediska výkonu na reálném hardware vyplácí!
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 08:58:07
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).
Ne, v tom žádná potíž není, protože to nikdy nebudu potřebovat. A i kdyby náhodou někdy bylo potřeba optimalizovat takový kód na použití procesorové cache, bude to stejně takové práce, že proti tomu je napsání jedné specifické kolekce brnkačka. Ostatně vy v C# také jako první budete muset udělat to, že opustíte obecná řešení v obecných knihovnách, protože ta obecnost optimalizaci brání.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 09:00:20
A že ta nejdůležitější a nejzákladnější zásada pro efektivní využití cache je naskládat objekty za sebe a neskákat zbytečně po pointerech?
Kdybyste nereagoval na komentář, kde jsem tohle psal, možná by to bylo i vtipné.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 09:14:20
Je to pole referencí a kdo bude tvrdit něco jiného tak ukazuje že Javě naprosto nerozumí!
Ještě jednou, v Javě se pojem „reference na objekt“ nepoužívá, protože se k objektu jinak než přes referenci nedostanete, takže se říká jenom „objekt“.

Ono ale při problémech s využitím procesorové cache je naprosto zásadní jak jsou data v paměti uložena!
Právě proto jsem psal, že budu řešit, jak mají být data uložena, a ne to, jak vypadá nějaké pole.

Naimplementujte si třeba velkou matici intů v jednorozměrném poli
Typická webová aplikace je plná velkých matic intů.

Přemýšlet o cache se dnes prostě z hlediska výkonu na reálném hardware vyplácí!
K reálnému hardware potřebujete ještě reálný software. A takového moc není, napsaného v Javě, který by pracoval s velkými maticemi intů a řešil problémy s procesorovou cache. A pokud takový je, jeho autoři snad vědí, jak mají optimalizovat.

Každopádně je velmi zábavná argumentace, že důvod, proč není moc webhostingů podporujících WAR, je ten, že se webhosteři bojí, že by tam měli plno aplikací pracujících s velkými maticemi intů, které budou špatně používat procesorovou cache.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 09:48:21
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).
Ostatně vy v C# také jako první budete muset udělat to, že opustíte obecná řešení v obecných knihovnách, protože ta obecnost optimalizaci brání.

Právě, že ne.

A není to jen o cachích. Je to i o práci GC: pro seznam 1000 dvojic (UserId, SalaryId) vy v Javě alokujete na heapu minimálně 3002 objektů, já v C# pouze 2 (instanci třídy List a instanci pole, samotné dvojice mohou být hodnotové typy = žádná alokace na heapu a žádná práce pro GC).

A je tu ještě další věc: Tím, že vy navrhujete používat kolekce mimo standardní knihovnu riskujete, že např. různí programátoři použití různé implementace - např. jeden použije jodd.util.collection.IntArrayList a druhý com.google.common.primitives.Ints.IntArrayAsList - a pak mezi nimi budete muset převádět. Pokud máte kvalitní implementaci ve standardní knihovně, je toto riziko nižší, neboť nemáte tolik důvodů používat třídu mimo standardní knihovnu.

Jak již psal dustin výše, naštěstí se Java dočká uživatelsky definovaných hodnotových typů i specializace generik - otázkou ovšem je kdy (navíc přechod na tyto nové featury nebude okamžitý).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 09:51:15
Ono ale při problémech s využitím procesorové cache je naprosto zásadní jak jsou data v paměti uložena!
Právě proto jsem psal, že budu řešit, jak mají být data uložena, a ne to, jak vypadá nějaké pole.
Právě že to je stále jedno a to samé. Pro efektivní využití cache bohatě stačí aby jazyk zbytečně nevkládal zbytečné skákání po pointerech. Koukněte na std::vector z C++. Ten pro běžné velikosti dat výkonnostně pomlátí teoreticky podstatně efektivnější kontejnery, prostě proto, že ukládá data za sebe do pole. A přitom je to naprosto generický kód, kde jako programátor nemusím vůbec nic řešit.

Tím, že Java nemá hodnotové typy a všechno je reference, úplně brutálně mrhá tím nejomezenějším zdrojem dnešních PC - velikostí cache a propustností sběrnice.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 10:19:50
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).
Ostatně vy v C# také jako první budete muset udělat to, že opustíte obecná řešení v obecných knihovnách, protože ta obecnost optimalizaci brání.
Právě, že ne.
Ale jistě že ano. Protože až to budete optimalizovat, první, co musíte udělat, je zamyslet se nad tím, jestli náhodou tisíciprvkový seznam dvojic UserId a Salary, nad kterým provádíte dlouhé výpočty, není nesmysl.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 10:29:37
Pro efektivní využití cache bohatě stačí aby jazyk zbytečně nevkládal zbytečné skákání po pointerech.
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.

Víte, proč výsledná rychlost programu obecně nezávisí na zvoleném programovacím jazyce? Protože Java programátoři nemají přístup k nízkoúrovňovým věcem a neznají detaily fungování JVM, takže tohle neřeší; zatímco C++ programátoři si myslí, že používají jazyk, který optimalizuje sám od sebe, takže to taky neřeší.

Tím, že Java nemá hodnotové typy a všechno je reference, úplně brutálně mrhá tím nejomezenějším zdrojem dnešních PC - velikostí cache a propustností sběrnice.
Vzhledem k tomu, že to na výkon programů nemá žádný vliv, tak je to jedno.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: dustin 17. 09. 2016, 10:30:04
Typická webová aplikace je plná velkých matic intů.

Ne, ale typická byznys aplikace je plná ArrayList<Integer>, které všude možně prochází ve smyčce (nebo streamem). Proto přímo autoři javy uznávají, že hlavně kvůli efektivitě využití CPU keší je v takovém případě vhodné místo objektů vyžadujících neustálé odskoky z referencí na objekty použít přímo hodnoty a dělají na implementaci do javy. Navíc možnost obalit primitivní typ významem a nechat kompilátor, aby to rovnou hlídal, je zatraceně užitečná (ID uživatele se nemá co míchat s ID článku, jenže jsou obojí inty)

http://cr.openjdk.java.net/~jrose/values/values-0.html
http://www.beyondjava.net/blog/java-8-types-revamping-javas-type-system/
http://openjdk.java.net/projects/valhalla/

Proč je dobré myslet na CPU keše - objem dat na zpracování neustále roste (např. u webů především evidence přístupů, jejichž zpracování má přímou vazbu na prodej inzerentům = byznys) a je jedině dobře, když poroste i rychlost JVM. Rychlost CPU už nijak moc neroste a paralelní zpracování na více jádrech by vyžadovalo podstatně větší úpravy aplikací, než využití hodnotových typů, až budou do javy přidané.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 10:31:59
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).
Ostatně vy v C# také jako první budete muset udělat to, že opustíte obecná řešení v obecných knihovnách, protože ta obecnost optimalizaci brání.
Právě, že ne.
Ale jistě že ano. Protože až to budete optimalizovat, první, co musíte udělat, je zamyslet se nad tím, jestli náhodou tisíciprvkový seznam dvojic UserId a Salary, nad kterým provádíte dlouhé výpočty, není nesmysl.
Nepíšete každý o něčem trochu jiném? Samozřejmě že se bude muset zamyslet. Ale pokud ten seznam dává smysl, tak je v C# hotov, protože ho má uložený v paměti efektivně i když použije standardní kontejner.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Pavel Tisnovsky 17. 09. 2016, 10:34:56
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.

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.

Re: pole objektu je pole referenci, ma to i vyhody, obecne dela GC v Jave "dobre" kdyz jsou objekty male, naopak "humongous" objekty se s GC dost perou (jdou primo do old generation atd.).
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 10:37:40
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).
Ostatně vy v C# také jako první budete muset udělat to, že opustíte obecná řešení v obecných knihovnách, protože ta obecnost optimalizaci brání.
Právě, že ne.
Ale jistě že ano. Protože až to budete optimalizovat, první, co musíte udělat, je zamyslet se nad tím, jestli náhodou tisíciprvkový seznam dvojic UserId a Salary, nad kterým provádíte dlouhé výpočty, není nesmysl.

Situací, kdy potřebujete pracovat s dvojicemi id a číslo je celá řada. Např. obyčejný e-shop chce nabízet produkty, které by se zákazníkovi mohly líbit - tj. pro každého zákazníka tam může mít seznam (id produktu, skóre) a z něj chce vždy vybrat např. 5 nejoblíbenějších produktů (s nejvyšším skóre), které zákazníkovi nebyly ukázány více než 4x (na to mj. potřebuje i mapu, id produktu -> kolikrát byl ukázán; pro níž byste v Javě opět nemohl použít standardní kolekci, pokud vám jde o alokaci paměti a výkon).

BTW, pokud se v C# rozhodnu takovéhle věci cachovat, tak jich nacachuji několikanásobně více než v Javě (protože zabírají několikanásobně méně paměti).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 10:41:49
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.
Samozřejmě že nebude. To je taky důvod, proč std::vector v dnešní době pomlátí std::list i když by podle asymptotické složitosti neměl.
Citace
Víte, proč výsledná rychlost programu obecně nezávisí na zvoleném programovacím jazyce? Protože Java programátoři nemají přístup k nízkoúrovňovým věcem a neznají detaily fungování JVM, takže tohle neřeší; zatímco C++ programátoři si myslí, že používají jazyk, který optimalizuje sám od sebe, takže to taky neřeší.
Takže to, že se dá prasit v každém jazyce a spousta lidí to dělá nějak vyplývá, že je to OK?
Citace
Vzhledem k tomu, že to na výkon programů nemá žádný vliv, tak je to jedno.
Samozřejmě že to má vliv. Ale není to na první pohled vidět, protože ten vliv je rozprostřený po celém programu. Profiler neukáže, že to někde drhne, protože to drhne +- všude.
Pokud to nemá žádný vliv, tak proč se v současné době tolik řeší Data-Oriented-Design?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: dustin 17. 09. 2016, 10:45:01
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.

Citace
Re: pole objektu je pole referenci, ma to i vyhody, obecne dela GC v Jave "dobre" kdyz jsou objekty male, naopak "humongous" objekty se s GC dost perou (jdou primo do old generation atd.).

Ano, ale pole hodnotových typů nebude přece o mnoho větší než původní pole referencí. A navíc tam nebudou ty malé objekty.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 10:48:01
Ale pokud ten seznam dává smysl
Ano, to je to klíčové. Porovnávat programovací jazyky podle jedné miliardtiny způsobu jejich využití je nesmysl.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 10:52:13
Ale pokud ten seznam dává smysl
Ano, to je to klíčové. Porovnávat programovací jazyky podle jedné miliardtiny způsobu jejich využití je nesmysl.
A je opravdu pole malých věcí něco tak vzácného? Já mám pocit, že se s ním setkávám skoro furt.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 11:01:10
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.

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.

Jenže u pole se musím o zvětšování/zmenšování starat ručně, zatímco u ArrayListu to udělají automaticky metody, které volám.

Citace
Docela bych rekl, ze je to dost umely priklad ne?

Netroufnu si posoudit, jak je to ve webových aplikacích na sdílených hostinzích.

Osobně mi mnou popsané problémy přijdou celkem časté v kódu, který píši.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 11:01:22
Situací, kdy potřebujete pracovat s dvojicemi id a číslo je celá řada. Např. obyčejný e-shop chce nabízet produkty, které by se zákazníkovi mohly líbit - tj. pro každého zákazníka tam může mít seznam (id produktu, skóre) a z něj chce vždy vybrat např. 5 nejoblíbenějších produktů (s nejvyšším skóre), které zákazníkovi nebyly ukázány více než 4x (na to mj. potřebuje i mapu, id produktu -> kolikrát byl ukázán; pro níž byste v Javě opět nemohl použít standardní kolekci, pokud vám jde o alokaci paměti a výkon).
Obyčejný e-shop data o všech produktech, o všech objednávkách zákazníka a statistiky zákaznického chování drží v paměti webového serveru. Aha. Proto se nemůžeme domluvit, protože v mém světě má e-shop tahle data v SQL databázi, případně něco v NoSQL.

Takže to, že se dá prasit v každém jazyce a spousta lidí to dělá nějak vyplývá, že je to OK?
Ne, z toho vyplývá, že když to někdo naprasí v nějakém jazyce, není to nutně chyba toho jazyka.


Samozřejmě že to má vliv. Ale není to na první pohled vidět, protože ten vliv je rozprostřený po celém programu. Profiler neukáže, že to někde drhne, protože to drhne +- všude.
Jestli procesor stráví v idle 40 % nebo 50 % času je úplně jedno.

Pokud to nemá žádný vliv, tak proč se v současné době tolik řeší Data-Oriented-Design?
Protože se tolik neřeší. Řeší se pouze ve specifických případech.

Jinak původně se tazatel ptal na porovnání webhostingů pro Javu a .NET z hlediska využití zdrojů. Pořád se bavím tou představou, jak webhoster chce poskytnout hosting pro WAR aplikace, ale pak si uvědomí, že ty aplikace určitě budou neefektivně využívat CPU cache, tak radši zvolí .NET.

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?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Pavel Tisnovsky 17. 09. 2016, 11:03:56
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.

Jasne o tom neni sporu, ale priznejme si - vetsina prikladu, co tady zaznela, nevede k pouziti ArrayListu, semanticky to byly vetsinou mnoziny (Set). Coz samozrejme nic nemeni na tom, ze i Set<int> a ne Set<Integer> by bylo fajn mit primo v zakladni knihovne. No nestalo se.

Citace
Citace
Re: pole objektu je pole referenci, ma to i vyhody, obecne dela GC v Jave "dobre" kdyz jsou objekty male, naopak "humongous" objekty se s GC dost perou (jdou primo do old generation atd.).

Ano, ale pole hodnotových typů nebude přece o mnoho větší než původní pole referencí. A navíc tam nebudou ty malé objekty.

To byla spis odpoved na tu cast diskuze, kde se resila pole objektu, coz v cecku odpovida poli struktur. Priklad:


struct x
{
    int id;
    float perc;
};

int main()
{
    struct x zaznam;
    struct x pol
e[1000];
    printf("%ld\n", sizeof(zaznam));
    printf("%ld\n", sizeof(pole));
    return 0;
}


Vypise na vystup 8 bajtu pro "zaznam" a 8000 bajtu pro pole.

V Jave to takto nejde, ma to svoje duvody:

1) historie
2) zajimave je, ze v Jave se nikdy nemusi resit velikosti objekty, protoze ty jsou bud konstantni nebo jde o pole, takze pole objektu je pohodicka - pole referenci. Ze ma nejaky objekt v sobe String? Neni problem, to je stejne reference na objekt s vnitrnim polem jako atributem. atd. Neni to asi vsude idealni, ale ta jednoduchost pro JVM z toho asi vyplyva.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 11:05:59
A je opravdu pole malých věcí něco tak vzácného? Já mám pocit, že se s ním setkávám skoro furt.
Jenže tady řešíme něco mnohem vzácnějšího – častou iteraci přes pole malých struktur (tj. ne primitivních typů), která ovšem programátorovi nestojí za optimalizaci.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 12:44:04
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.

Spojové struktury jako seznamy a stromy se právě z důvodu využití cache dnes moc nepoužívají. Přečti si něco o cache obvious algoritmech.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 12:53:43
A je opravdu pole malých věcí něco tak vzácného? Já mám pocit, že se s ním setkávám skoro furt.
Jenže tady řešíme něco mnohem vzácnějšího – častou iteraci přes pole malých struktur (tj. ne primitivních typů), která ovšem programátorovi nestojí za optimalizaci.

Jakou optimalizaci? V jiných jazycích je to triviální. Volbu správné datové struktury bych optimalizací nenazýval.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 13:21:14
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.

Spojové struktury jako seznamy a stromy se právě z důvodu využití cache dnes moc nepoužívají. Přečti si něco o cache obvious algoritmech.
To je ale v rozporu s tím, co psal JSH, že ke správnému využití cache stačí použít správný programovací jazyk. Přečíst by si to tedy měl JSH.

Jakou optimalizaci? V jiných jazycích je to triviální.
Asi byste si měl přečíst něco o cache obvious algoritmech. Dozvěděl byste se třeba, že se spojové seznamy a stromy nepoužívají, a to bez ohledu na programovací jazyk – protože ten to nijak magicky nezachrání.

Volbu správné datové struktury bych optimalizací nenazýval.
Tak to byste si měl něco přečíst i o datových strukturách. Protože jedna datová struktura může být vhodná z hlediska paměťové náročnosti, obvykle jiná bývá vhodná z hlediska rychlosti (a to je ještě různé pro čtení a pro zápis), jiná datová struktura může být vhodná z hlediska snadnosti použití nebo složitosti implementace. Která z nich je ta správná? Obvykle ta, co se nejsnáz používá, ale někdy je potřeba optimalizovat – a pak je často nutné změnit datovou strukturu.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 13:37:01
Situací, kdy potřebujete pracovat s dvojicemi id a číslo je celá řada. Např. obyčejný e-shop chce nabízet produkty, které by se zákazníkovi mohly líbit - tj. pro každého zákazníka tam může mít seznam (id produktu, skóre) a z něj chce vždy vybrat např. 5 nejoblíbenějších produktů (s nejvyšším skóre), které zákazníkovi nebyly ukázány více než 4x (na to mj. potřebuje i mapu, id produktu -> kolikrát byl ukázán; pro níž byste v Javě opět nemohl použít standardní kolekci, pokud vám jde o alokaci paměti a výkon).
Obyčejný e-shop data o všech produktech, o všech objednávkách zákazníka a statistiky zákaznického chování drží v paměti webového serveru.

Nic takového jsem nenapsal: Např. slovo objednávka jsem nezmínil ani jednou. A rozhodně jsem neříkal, kde se ta data drží. Mluvil jsem o vektoru dvojic (id produktu, skóre), který si načtete třeba z databáze nebo si ho spočítáte, pokud již nebyl spočten a uložen v cachi.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 13:42:36
To je ale v rozporu s tím, co psal JSH, že ke správnému využití cache stačí použít správný programovací jazyk. Přečíst by si to tedy měl JSH.
Kde jsem něco takového psal?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 13:45:08
A je opravdu pole malých věcí něco tak vzácného? Já mám pocit, že se s ním setkávám skoro furt.
Jenže tady řešíme něco mnohem vzácnějšího – častou iteraci přes pole malých struktur (tj. ne primitivních typů), která ovšem programátorovi nestojí za optimalizaci.

Nejenom - řešíme tu i to, že takové pole nebo seznam zabere v Javě více paměti (a to i několikanásobně) než v C#, kde jsou ty struktury deklarovány jako struct.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 13:48:04
Nic takového jsem nenapsal: Např. slovo objednávka jsem nezmínil ani jednou. A rozhodně jsem neříkal, kde se ta data drží. Mluvil jsem o vektoru dvojic (id produktu, skóre), který si načtete třeba z databáze nebo si ho spočítáte, pokud již nebyl spočten a uložen v cachi.
Normální program si z databáze nenačte pět dvojic (id produktu, skóre), ale načte si pět záznamů (název produktu, odkaz na produkt, odkaz na obrázek produktu, skóre). Optimalizovat uložení těch pěti záznamů v paměti aplikace tak, aby se vešly do cache procesoru, je nesmysl na entou. Ale pokud si někdo chce hrát se strukturami proměnlivé délky (minimálně ten název produktu bude text s různou délkou), ať si to užije. Drobným problémem bude, že dotyčný autor sice bude mít optimalizovaný výpis (ne získání) 5 doporučených produktů, akorát mu k tomu bude chybět ten e-shop (který by za tu dobu napsal ten, kdo neřeší nesmyslné optimalizace).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 13:50:01
To je ale v rozporu s tím, co psal JSH, že ke správnému využití cache stačí použít správný programovací jazyk. Přečíst by si to tedy měl JSH.
Kde jsem něco takového psal?

Pro efektivní využití cache bohatě stačí aby jazyk zbytečně nevkládal zbytečné skákání po pointerech.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 14:04:26
Nic takového jsem nenapsal: Např. slovo objednávka jsem nezmínil ani jednou. A rozhodně jsem neříkal, kde se ta data drží. Mluvil jsem o vektoru dvojic (id produktu, skóre), který si načtete třeba z databáze nebo si ho spočítáte, pokud již nebyl spočten a uložen v cachi.
Normální program si z databáze nenačte pět dvojic (id produktu, skóre), ale načte si pět záznamů (název produktu, odkaz na produkt, odkaz na obrázek produktu, skóre). Optimalizovat uložení těch pěti záznamů v paměti aplikace tak, aby se vešly do cache procesoru, je nesmysl na entou. Ale pokud si někdo chce hrát se strukturami proměnlivé délky (minimálně ten název produktu bude text s různou délkou), ať si to užije. Drobným problémem bude, že dotyčný autor sice bude mít optimalizovaný výpis (ne získání) 5 doporučených produktů, akorát mu k tomu bude chybět ten e-shop (který by za tu dobu napsal ten, kdo neřeší nesmyslné optimalizace).

Ne, to jste mne špatně pochopil. Z databáze si načtete třeba 100 nebo 1000 dvojic (id produktu, skóre) (případně těch 100 nebo 1000 dvojic spočtete na základě jiných dat, která máte v databázi). Pokud jste ty dvojice počítal, tak je setřídíte sestupně dle skóre (předpokládám, že do databáze je již ukládáte setříděné). A pak vyberete id 5 produktů s nejvyšším skóre, které uživatel viděl 4x nebo méně. A takto vybrané produktu mu ukážete, protože si myslíte, že by o ně mohl mít zájem.

Co možná není zřejmé je, že ten vektor je pro každého uživatele jiný.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: andy 17. 09. 2016, 14:17:32
Ak mam web aplikaciu (o ktorych je rec) ktora je tak vytazena, ze riesim cache CPU, tak zivotnost dat v CPU je tak tazko predpovedatelna, ze to nema zmysel riesit (to nie je graficka aplikacia ze si alokujem pole a to pole tam ostane ako dlho potrebujem..). Ak je zataz mala, tak to tiez nema zmysel riesit, lebo IO je radovo pomalsie ako cache cpu. Moj nazor je, ze je lepsie mat vsetky data klienta ako objekty a najlepsie alokovane kratko za sebou. Tak je pravdepodobnost, ze pri nacitani hodnoty sa natiahnu do cache aj suvisiace hodnoty daneho usera (ktoreho request prave obsluhujem), pretoze v eden space sa data alokuju za sebou a navyse jvm vklada prefetch instrukcie. Obcas sa da prechytracit JVM, ale vacsinou je to strata casu a je lepsie sa sustredit na lepsi algoritmus.

Okrem toho ked si chcem cachovat data v pamati, tak dnes uz v jave existuju kniznice, ktore vedia cachovat objekty priamo do offheap pamate bez zbytocnej vaty. Je to skaredy hack, ale funguje to.

Ze su hostingy pre .net je podla mojho nazoru jednoducho preto, ze IIS ma na to nejake pasivacne ficurky (s ktorymi sa da dosiahnut dost vysoka hustota appiek/server pri beznych=90% casu idle apkach) a java servery ziadne take ficurky nemaju. S modernymi java frameworkami ktore sa nestartuju minuty ale sekundy sa to da urobit aj s javou (napr google app engine myslim pasivuje idle java aplikacie), ale kto by to robil pri cene VPS pod 5 eur/mesiac?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: JSH 17. 09. 2016, 14:20:55
To je ale v rozporu s tím, co psal JSH, že ke správnému využití cache stačí použít správný programovací jazyk. Přečíst by si to tedy měl JSH.
Kde jsem něco takového psal?

Pro efektivní využití cache bohatě stačí aby jazyk zbytečně nevkládal zbytečné skákání po pointerech.
Jo tohle. Měl jsem za to, že je z kontextu jasné, co tím myslím. Moje chyba :(
gl vystihl dobře, co jsem se snažil říct.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 14:26:53
CPU výkon má smysl řešit například při párování nabídek podle nějakých složitějších kriterií, nebo v map a reduce funkcích u různých nosql databází, hadoopu apod. Těch případů je určitě spousta.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 17. 09. 2016, 14:35:29
Jak to teda třeba ten Hadoop dělá, když je psaný v Javě? Nebo jen na rootu mají problém s cachí, která je sice asi důležitá, ale ne moc? Jako jestli třeba Hadoop není rozbitý a neměli by ho předělat podle vás.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 14:37:06
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.

Spojové struktury jako seznamy a stromy se právě z důvodu využití cache dnes moc nepoužívají. Přečti si něco o cache obvious algoritmech.
To je ale v rozporu s tím, co psal JSH, že ke správnému využití cache stačí použít správný programovací jazyk. Přečíst by si to tedy měl JSH.

On nic takového nepsal.

Jakou optimalizaci? V jiných jazycích je to triviální.
Asi byste si měl přečíst něco o cache obvious algoritmech. Dozvěděl byste se třeba, že se spojové seznamy a stromy nepoužívají, a to bez ohledu na programovací jazyk – protože ten to nijak magicky nezachrání.

Na tom se shodneme. Myslel jsem tím pole struktur, to je v jiných jazycích triviální.

Volbu správné datové struktury bych optimalizací nenazýval.
Tak to byste si měl něco přečíst i o datových strukturách. Protože jedna datová struktura může být vhodná z hlediska paměťové náročnosti, obvykle jiná bývá vhodná z hlediska rychlosti (a to je ještě různé pro čtení a pro zápis), jiná datová struktura může být vhodná z hlediska snadnosti použití nebo složitosti implementace. Která z nich je ta správná? Obvykle ta, co se nejsnáz používá, ale někdy je potřeba optimalizovat – a pak je často nutné změnit datovou strukturu.

Pokud se používají obě možnosti stejně snadno, vyberu tu efektivnější.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 14:40:48
Jak to teda třeba ten Hadoop dělá, když je psaný v Javě? Nebo jen na rootu mají problém s cachí, která je sice asi důležitá, ale ne moc? Jako jestli třeba Hadoop není rozbitý a neměli by ho předělat podle vás.

Pokud redukční funkce provádí něco složitějšího, tak je každé její zrychlení sakra znát.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 14:52:14
Jak to teda třeba ten Hadoop dělá, když je psaný v Javě? Nebo jen na rootu mají problém s cachí, která je sice asi důležitá, ale ne moc? Jako jestli třeba Hadoop není rozbitý a neměli by ho předělat podle vás.

Distribuce od Cloudery má tyto problémy také. Proto distribuce od MapR převedla některé části do C++.

Jinak je to přesně, jak říká gl - v MR jobech nebo Spark jobech často pracujete s velkými kolekcemi dat a např. tím, že někde přestanete zbytečně boxovat ušetříte stovky MB paměti ==> díky čemuž může na jednom nodu běžet více jobů.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 15:21:02
Ne, to jste mne špatně pochopil. Z databáze si načtete třeba 100 nebo 1000 dvojic (id produktu, skóre) (případně těch 100 nebo 1000 dvojic spočtete na základě jiných dat, která máte v databázi). Pokud jste ty dvojice počítal, tak je setřídíte sestupně dle skóre (předpokládám, že do databáze je již ukládáte setříděné). A pak vyberete id 5 produktů s nejvyšším skóre, které uživatel viděl 4x nebo méně. A takto vybrané produktu mu ukážete, protože si myslíte, že by o ně mohl mít zájem.
Nikoli, nepochopil jsem vás špatně. Akorát jsem doufal, že alespoň tušíte, jak se nějaká data zpracovávají. Ale je to typické. O optimalizaci pro cache procesoru píše někdo, kdo netuší, že SELECT z databáze má také podmínkovou část WHERE a část ORDER BY pro řazení dat. Když nebudete tahat všechna data z databáze do aplikace a třídit a řadit je tam, ale místo toho se naučíte používat databázi, budete to oproti hrátkami s cache procesoru milionkrát účinnější optimalizace.

CPU výkon má smysl řešit například při párování nabídek podle nějakých složitějších kriterií, nebo v map a reduce funkcích u různých nosql databází, hadoopu apod. Těch případů je určitě spousta.
Přičemž nic z toho se nebude řešit ve webové aplikaci, ale v databázi.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: andy 17. 09. 2016, 15:35:48
Nikoli, nepochopil jsem vás špatně. Akorát jsem doufal, že alespoň tušíte, jak se nějaká data zpracovávají. Ale je to typické. O optimalizaci pro cache procesoru píše někdo, kdo netuší, že SELECT z databáze má také podmínkovou část WHERE a část ORDER BY pro řazení dat. Když nebudete tahat všechna data z databáze do aplikace a třídit a řadit je tam, ale místo toho se naučíte používat databázi, budete to oproti hrátkami s cache procesoru milionkrát účinnější optimalizace.
Na toto som celkom zabudol. Uz som riesil viac takychto aplikacii, kde pristup "ja to urobim lepsie len co si stiahnem polku db" sposobil, ze pri 30 req/s sa zahltila siet (iba 1Gbit) a cpu mohlo ist na dovolenku.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 17. 09. 2016, 15:38:47
Pořád mi to nějak nesedí. Máme luxusní SW psaný v Javě (Hadoop, Cassandra, atd.), který se používá na největší věci a i když to podle rootu nejde kvůli cachi, tak prostě pořád není konkurence v něčem jiném. Takže buď máte pravdu a je to strašný problém, ale pak žijeme každý v jiném světě a nebo to není až takový problém, protože jsou daleko důležitější věci po cestě, než zarovnávání objektů do paměti.

Nebo je to úplně jinak a dozvím se to tady! :D
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 15:40:45
Ne, to jste mne špatně pochopil. Z databáze si načtete třeba 100 nebo 1000 dvojic (id produktu, skóre) (případně těch 100 nebo 1000 dvojic spočtete na základě jiných dat, která máte v databázi). Pokud jste ty dvojice počítal, tak je setřídíte sestupně dle skóre (předpokládám, že do databáze je již ukládáte setříděné). A pak vyberete id 5 produktů s nejvyšším skóre, které uživatel viděl 4x nebo méně. A takto vybrané produktu mu ukážete, protože si myslíte, že by o ně mohl mít zájem.
Nikoli, nepochopil jsem vás špatně. Akorát jsem doufal, že alespoň tušíte, jak se nějaká data zpracovávají. Ale je to typické. O optimalizaci pro cache procesoru píše někdo, kdo netuší, že SELECT z databáze má také podmínkovou část WHERE a část ORDER BY pro řazení dat. Když nebudete tahat všechna data z databáze do aplikace a třídit a řadit je tam, ale místo toho se naučíte používat databázi, budete to oproti hrátkami s cache procesoru milionkrát účinnější optimalizace.

CPU výkon má smysl řešit například při párování nabídek podle nějakých složitějších kriterií, nebo v map a reduce funkcích u různých nosql databází, hadoopu apod. Těch případů je určitě spousta.
Přičemž nic z toho se nebude řešit ve webové aplikaci, ale v databázi.

Psal jsem spíš o nějakém předpočítávání dat pro sql databázi, případně o nosql, databázích.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 15:44:25
Pořád mi to nějak nesedí. Máme luxusní SW psaný v Javě (Hadoop, Cassandra, atd.), který se používá na největší věci a i když to podle rootu nejde kvůli cachi, tak prostě pořád není konkurence v něčem jiném. Takže buď máte pravdu a je to strašný problém, ale pak žijeme každý v jiném světě a nebo to není až takový problém, protože jsou daleko důležitější věci po cestě, než zarovnávání objektů do paměti.

Nebo je to úplně jinak a dozvím se to tady! :D
Samozřejmě jsou daleko důležitější věci, než je zarovnání objektů v paměti. A tam, kde by tyhle projekty narážely na problém se zarovnáním objektů v paměti, tak to jejich vývojáři prostě vyřeší prostředky Javy – pro autory Hadoop nebo Cassandy určitě není nepřekonatelný problém, že IntArrayList není součástí standardní knihovny.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 17. 09. 2016, 15:44:31
Pořád mi to nějak nesedí. Máme luxusní SW psaný v Javě (Hadoop, Cassandra, atd.), který se používá na největší věci a i když to podle rootu nejde kvůli cachi, tak prostě pořád není konkurence v něčem jiném. Takže buď máte pravdu a je to strašný problém, ale pak žijeme každý v jiném světě a nebo to není až takový problém, protože jsou daleko důležitější věci po cestě, než zarovnávání objektů do paměti.

Nebo je to úplně jinak a dozvím se to tady! :D

Je úplně jedno v čem je to napsané. Hadoop pouze předává data programům, které jsi napsal ty.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 16:15:41
Ne, to jste mne špatně pochopil. Z databáze si načtete třeba 100 nebo 1000 dvojic (id produktu, skóre) (případně těch 100 nebo 1000 dvojic spočtete na základě jiných dat, která máte v databázi). Pokud jste ty dvojice počítal, tak je setřídíte sestupně dle skóre (předpokládám, že do databáze je již ukládáte setříděné). A pak vyberete id 5 produktů s nejvyšším skóre, které uživatel viděl 4x nebo méně. A takto vybrané produktu mu ukážete, protože si myslíte, že by o ně mohl mít zájem.
kdo netuší, že SELECT z databáze má také podmínkovou část WHERE a část ORDER BY pro řazení dat.

To nemusí být možné, protože ne každá databáze to dokáže (BTW potřebujete navíc ještě JOIN s tabulkou statistik, kolikrát byl produkt uživateli zobrazen).

Citace
Když nebudete tahat všechna data z databáze do aplikace a třídit a řadit je tam, ale místo toho se naučíte používat databázi, budete to oproti hrátkami s cache procesoru milionkrát účinnější optimalizace.

Stahujete max pár kb dat. A to jestli se vyplatí výpočet provést na straně db záleží na konkrétní db (běžné relační db například nemusí unést zápis při aktualizaci skóre; pokud navíc vektory se skóre nemáte uloženy v db, ale počítáte z jiných dat, výpočet je o něco složitější - menší pravděpodobnost, že se vyplatí provádět ho uvnitř db).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 16:31:34
Pořád mi to nějak nesedí. Máme luxusní SW psaný v Javě (Hadoop, Cassandra, atd.), který se používá na největší věci a i když to podle rootu nejde kvůli cachi, tak prostě pořád není konkurence v něčem jiném. Takže buď máte pravdu a je to strašný problém, ale pak žijeme každý v jiném světě a nebo to není až takový problém, protože jsou daleko důležitější věci po cestě, než zarovnávání objektů do paměti.

Jak říkám, nejde jen o cache, ale i o množství využité paměti a nápor na GC. V Javě se to pak řeší tak, že se dávají data mimo heap - což je ale těžší a dražší na vývoj.

Kromě toho, nikdo nepsal, že to nejde, ale že je to méně šetrné ke zdrojům.

Citace
tak prostě pořád není konkurence v něčem jiném

Alternativy existují, ale jsou méně podporované než Hadoop MR.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 16:42:51
Stahujete max pár kb dat. A to jestli se vyplatí výpočet provést na straně db záleží na konkrétní db (běžné relační db například nemusí unést zápis při aktualizaci skóre; pokud navíc vektory se skóre nemáte uloženy v db, ale počítáte z jiných dat, výpočet je o něco složitější - menší pravděpodobnost, že se vyplatí provádět ho uvnitř db).
Takže těch pár kB dat, která je problém přenést z hlavní paměti do cache procesoru, raději budete posílat po síti. Jo, to je úžasná optimalizace.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 17:04:31
Stahujete max pár kb dat. A to jestli se vyplatí výpočet provést na straně db záleží na konkrétní db (běžné relační db například nemusí unést zápis při aktualizaci skóre; pokud navíc vektory se skóre nemáte uloženy v db, ale počítáte z jiných dat, výpočet je o něco složitější - menší pravděpodobnost, že se vyplatí provádět ho uvnitř db).
Takže těch pár kB dat, která je problém přenést z hlavní paměti do cache procesoru, raději budete posílat po síti.

Ano, pokud to nejde spočítat v db (db nestíhá nebo to neumí). Navíc v tom svém řešení mohu výsledky z db cachovat - těch pár kb (vektor obsahující id produktů a skóre) se po určitou dobu nemění a dále jako bonus nemusím pokaždé aktualizovat tabulku v db, kolikrát byl uživateli určitý produkt nabídnut.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 17. 09. 2016, 17:15:53
Ano, pokud to nejde spočítat v db (db nestíhá nebo to neumí).
Pokud to nejde spočítat v db, nemá smysl řešit procesorovou cache, ale zařídit, aby to v db spočítat šlo – rozdíl ve zlepšení je několik řádů.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 17. 09. 2016, 17:40:27
Ano, pokud to nejde spočítat v db (db nestíhá nebo to neumí).
Pokud to nejde spočítat v db, nemá smysl řešit procesorovou cache, ale zařídit, aby to v db spočítat šlo – rozdíl ve zlepšení je několik řádů.

Aby to šlo, musel byste třeba vyměnit databázi, jenže, jak jsem psal výše, jiná databáze (např. relační) už nemusí zvládnout zátěž při aktualizaci těch vektorů.

Pak je tu otázka, zda naopak nedojde ke zhoršení, když ten výpočet bude trošku složitější (v db nebudou přímo vektory se skóre, ale budou tam jiná data, z nichž se tyto vektory počítají (např. každá složka vektoru bude spočtena jako skalární součin jiných vektorů v databázi - přičemž v aplikaci můžete na výpočet použít specializovanou matematickou knihovnu, v SQL máte smůlu)).
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: NooN 17. 09. 2016, 23:49:50
Aby to šlo, musel byste třeba vyměnit databázi, jenže, jak jsem psal výše, jiná databáze (např. relační) už nemusí zvládnout zátěž při aktualizaci těch vektorů.

Pak je tu otázka, zda naopak nedojde ke zhoršení, když ten výpočet bude trošku složitější (v db nebudou přímo vektory se skóre, ale budou tam jiná data, z nichž se tyto vektory počítají (např. každá složka vektoru bude spočtena jako skalární součin jiných vektorů v databázi - přičemž v aplikaci můžete na výpočet použít specializovanou matematickou knihovnu, v SQL máte smůlu)).
Zasa jeden co si mysli, ze to zoptimalizuje lepsie ako SQL server.
Staci viac porozumiet SQL serveru a garantujem ti ze mas po probleme...
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 18. 09. 2016, 01:07:34
Aby to šlo, musel byste třeba vyměnit databázi, jenže, jak jsem psal výše, jiná databáze (např. relační) už nemusí zvládnout zátěž při aktualizaci těch vektorů.

Pak je tu otázka, zda naopak nedojde ke zhoršení, když ten výpočet bude trošku složitější (v db nebudou přímo vektory se skóre, ale budou tam jiná data, z nichž se tyto vektory počítají (např. každá složka vektoru bude spočtena jako skalární součin jiných vektorů v databázi - přičemž v aplikaci můžete na výpočet použít specializovanou matematickou knihovnu, v SQL máte smůlu)).
Zasa jeden co si mysli, ze to zoptimalizuje lepsie ako SQL server.
Staci viac porozumiet SQL serveru a garantujem ti ze mas po probleme...

Celkem o tom pochybuji - máte např. nějaká měření, kde SQL Server počítá skalární součiny rychleji než aplikace v C#?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: borekz 18. 09. 2016, 07:28:42
Celkem o tom pochybuji - máte např. nějaká měření, kde SQL Server počítá skalární součiny rychleji než aplikace v C#?
Pokud např. v MySQL bude skalární součin počítat UDF v C++, bude to rychlé jako C++. Vsadím se, že databáze s podporou GIS budou mít takové funkce vestavěné. Jde hlavně o to, že na moderním HW je výpočet součinu záležitostí několika strojových cyklů, narozdíl od režie na poslání vektoru přes soket do aplikace v C#. V Javě má navíc překvapivě vysokou režii ovladač JDBC. Mám změřeno, že načtení velkého objemu z MySQL je výrazně rychlejší v C přes libmysqlclient než v Javě přes Connector/J a navíc se nejprve vše načítá do RAM, než lze z Resultsetu načíst první záznam. Pokud je výstup výpočtu menší než vstup, je obvykle výhodnější provést výpočet v db serveru.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 18. 09. 2016, 08:57:25
Celkem o tom pochybuji - máte např. nějaká měření, kde SQL Server počítá skalární součiny rychleji než aplikace v C#?
Pokud např. v MySQL bude skalární součin počítat UDF v C++, bude to rychlé jako C++.

Ano, to je pravda. V SQL Serveru se používají CLR funkce - tj. tímto trikem byste dosáhl podobné rychlosti, pokud by data byla uložena ve formátu, jenž je vhodný pro násobení.

Citace
Jde hlavně o to, že na moderním HW je výpočet součinu záležitostí několika strojových cyklů, narozdíl od režie na poslání vektoru přes soket do aplikace v C#.

Souhlasím - nepočítal jsem s použitím UDF. Tj. už věřím, že byste celý výpočet, i když je ve skutečnosti složitější, mohl přesunout do SQL Serveru aniž by došlo ke zpomalení.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 18. 09. 2016, 09:52:08
Celkem o tom pochybuji - máte např. nějaká měření, kde SQL Server počítá skalární součiny rychleji než aplikace v C#?
Máte vy nějaká měření, že načíst všechna data z disku, přenést je po síti a pak je možná spočítat rychleji v C# je rychlejší, než načíst z disku jenom potřebná data, spočítat to možná pomaleji na SQL serveru a pak přenést po síti jenom výsledek? Je pozoruhodné, jak se pořád snažíte optimalizovat práci procesoru, ale zbytečné načítání z disku nebo přenosy po síti vám vůbec nevadí. Přitom disk a síť jsou ty hlavní brzdy, ty vaše výpočty vám procesoru udělá v době, kdy bude čekat na další síťový paket, a ještě se u toho bude flákat.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 18. 09. 2016, 10:12:16
Celkem o tom pochybuji - máte např. nějaká měření, kde SQL Server počítá skalární součiny rychleji než aplikace v C#?
Máte vy nějaká měření, že načíst všechna data z disku, přenést je po síti a pak je možná spočítat rychleji v C# je rychlejší, než načíst z disku jenom potřebná data, spočítat to možná pomaleji na SQL serveru a pak přenést po síti jenom výsledek? Je pozoruhodné, jak se pořád snažíte optimalizovat práci procesoru, ale zbytečné načítání z disku nebo přenosy po síti vám vůbec nevadí. Přitom disk a síť jsou ty hlavní brzdy, ty vaše výpočty vám procesoru udělá v době, kdy bude čekat na další síťový paket, a ještě se u toho bude flákat.

Nedělám, to, co popisujete.

Do aplikace v C# se posílá nejvýše 1 vektor (pro uživatele) vektory, s nimiž se budou dělat skalární součiny (pro produkty) tam již jsou. Někdy tam dokonce je i ten vektor pro uživatele. Navíc, pokud máte pouze jeden výdejový server (ta aplikace v C# běží na 1 serveru), tak nemusíte na SQL Server pokaždé posílat, kolikrát uživatel daný produkt viděl (zatímco, když to budete počítat na SQL Serveru, tak to musíte posílat po každé), díky čemu síťový i diskový provoz naopak ušetříte.

Pokud jste malý e-shop na sdíleném hostingu, tak v db ani nemusíte mít povolené UDF, takže to nespočítáte tak rychle. Pokud jste velký e-shop, tak relační databáze nemusí ustát aktualizaci těch vektorů - tj. budete používat nějakou NoSQL databázi, ve které to ovšem ani nemusí jít spočítat.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 18. 09. 2016, 10:33:04
tak nemusíte na SQL Server pokaždé posílat, kolikrát uživatel daný produkt viděl
Bývá zvykem data, která chcete uložit, ukládat do nějaké databáze – ať už SQL nebo NoSQL. Držet je jenom v paměti webového serveru není dobrý nápad, protože o ně přijdete při prvním ukončení serveru (třeba kvůli aktualizaci).

Pokud jste malý e-shop na sdíleném hostingu, tak v db ani nemusíte mít povolené UDF, takže to nespočítáte tak rychle.
Jenže rychlé počítání nikoho nezajímá, protože i to nejpomalejší počítání bude pořád o několik řádů rychlejší, než zbytečné načítání dat z  disku nebo jejich zbytečné posílání po síti.

Pokud jste velký e-shop, tak relační databáze nemusí ustát aktualizaci těch vektorů - tj. budete používat nějakou NoSQL databázi, ve které to ovšem ani nemusí jít spočítat.
Pokud to v té NoSQL databázi nepůjde spočítat, budu řešit, jak použít lepší NoSQL databázi a ušetřit tím desítky nebo stovky milisekund. Nebudu řešit výkon CPU, abych ušetřil mikrosekundy.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 18. 09. 2016, 11:01:47
tak nemusíte na SQL Server pokaždé posílat, kolikrát uživatel daný produkt viděl
Bývá zvykem data, která chcete uložit, ukládat do nějaké databáze – ať už SQL nebo NoSQL. Držet je jenom v paměti webového serveru není dobrý nápad, protože o ně přijdete při prvním ukončení serveru (třeba kvůli aktualizaci).

Když dojde k normálnímu ukončení, tak aplikace dostane zprávu předem - tj. data může uložit.

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.

Citace
i to nejpomalejší počítání bude pořád o několik řádů rychlejší, než zbytečné načítání dat z  disku nebo jejich zbytečné posílání po síti.

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.

Citace
Pokud to v té NoSQL databázi nepůjde spočítat, budu řešit, jak použít lepší NoSQL databázi a ušetřit tím desítky nebo stovky milisekund. Nebudu řešit výkon CPU, abych ušetřil mikrosekundy.

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).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: alfonzo 18. 09. 2016, 12:58:40
je sranda, ako tu niektori porovnavaju narocnost JVM s .NETom. Nakolko vacsina z vas tu s .NETom ani nerobi, lebo windows, lebo microsoft, hlavne ze sa vyjadruju. :)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 18. 09. 2016, 13:22:58
Přesně. .Net je shit pro hloupé lidi z Windows světa a není žádný důvod to využívat na pořádných systémech. Stejně to o moc lepší být nemůže. JVM a Java je prostě nejlepší.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 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?
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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.

Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Filip Jirsák 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Martin 19. 09. 2016, 00:24:32
A těch méně než 10 ms bylo docíleno optimalizacemi zaměřenými na cache?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 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.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 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í.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Fbi 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.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 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ázev: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: N 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.
Název: Re:Pametova a vypocetni narocnost JVM vs .NET
Přispěvatel: dustin 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í
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 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.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 19. 09. 2016, 18:38:10
Zkus si porovnat rychlost průchodu dlouhého pole.
Porovnat s čím? A co znamená „průchod pole“?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 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 (http://scala-miniboxing.org/benchmarks.html) 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 (https://www.youtube.com/watch?v=TJHgp1ugKGM&feature=youtu.be&t=30m0s) (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.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 19. 09. 2016, 20:58:33
Podívejte se třeba, jak pomáhá Miniboxing (http://scala-miniboxing.org/benchmarks.html) 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 (https://www.youtube.com/watch?v=TJHgp1ugKGM&feature=youtu.be&t=30m0s) (30. minuta).

Kde je tam ta Java a moderní HW? Tyhle optimalizace klidně může dělat JVM, ale programátor by se moc starat neměl.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 19. 09. 2016, 21:16:17
Podívejte se třeba, jak pomáhá Miniboxing (http://scala-miniboxing.org/benchmarks.html) 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 (https://www.youtube.com/watch?v=TJHgp1ugKGM&feature=youtu.be&t=30m0s) (30. minuta).

Tyhle optimalizace klidně může dělat JVM, ale programátor by se moc starat neměl.

Ano, ale většina JVM to nedělá (možná, že některé implementace, které neznám, to dělají). Místo toho se plánuje, že se část toho, co .NET umí už 10 let (od C# 2.0), přidá do Javy 10 (viz Project Valhalla (https://en.wikipedia.org/wiki/Project_Valhalla_(Java_language))).

Citace
Kde je tam ta Java a moderní HW?

Myslím, že výsledky Miniboxingu lze vztáhnout i na Javu - Scala byla měřena nad JVM. Ta měření jsou dělána na moderním HW.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: javaman (( 19. 09. 2016, 21:39:35
Asi to zase taková pecka nebude. Čistě teoreticky by to určitě JVM mohlo při nějakých případech dělat. Programátora by to zajímat moc nemělo. To, že to přidají, je fajn, ale třeba to také nebude až tak využívané, když .Net se nepoužívá a Java je nejrozšířenější.

S tou Scalou máš asi pravdu, ale moc nebudu zkoumat ty testy. Většinou bývají trochu nereálné. Každopádně i kdyby to byla nejlepší věc na světě, tak jsem získal dvojnásobný výkon při nějakých operacích a čtyřnásobný při jiných. To mě moc jako nebere, pokud je to tvoje dobré využití cache. Pokud je to na něco jiného, tak OK, ale i tak je to moc slabé. Když optimalizovat, tak pořádně. Ale lepší než nic, to je jasné.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 19. 09. 2016, 21:50:15
když .Net se nepoužívá a Java je nejrozšířenější.

V tom máte pravdu. Hlavní problém .NETu je IMO závislost na Microsoftu (zvláště, když si člověk vzpomene, jak se MS chová).

Navíc Java má kvalitnější nástroje (např. nejrozšířenější build systémy pro .NET jsou celkem katastrofální oproti Gradlu nebo Mavenu).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 19. 09. 2016, 22:04:12
Zkus si porovnat rychlost průchodu dlouhého pole.
Porovnat s čím? A co znamená „průchod pole“?

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define DIST(x1,x2,y1,y2) \
  (sqrt((x2 - x1)*(x2 - x1) + ((y2 - y1)*(y2 - y1))))

#define ARR_LEN 1000000

typedef struct Point {
  int x;
  int y;
} Point;

int main()
{
  struct Point *points = malloc(ARR_LEN * sizeof(struct Point));
  struct Point **ppoints = malloc(ARR_LEN * sizeof(struct Point*));
  struct Point **ppoints2 = malloc(ARR_LEN * sizeof(struct Point*));
  double path_length = 0;
  int i;
  int index;
  for(i = 0; i < ARR_LEN; ++i){
    index = i % 2 == 0 ? i>>1 : ARR_LEN - (i>>1) - 1;
    ppoints2[index] = malloc(sizeof(struct Point));
  }
  for(i = 0; i < ARR_LEN; ++i){
    points[i].x = rand() % 20;
    points[i].y = rand() % 20;
    ppoints[i] = &points[i];
    ppoints2[i]->x = points[i].x;
    ppoints2[i]->y = points[i].y;
  }
  clock_t begin = clock();
  for(i = 1; i < ARR_LEN; ++i){
    path_length += DIST(points[i].x, points[i - 1].x,
                        points[i].y, points[i - 1].y);
  }
  clock_t end = clock();
  double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("length %f time spent %f\n", path_length, time_spent);
  begin = clock();
  path_length = 0;
  for(i = 1; i < ARR_LEN; ++i){
    path_length += DIST(ppoints[i]->x, ppoints[i - 1]->x,
                        ppoints[i]->y, ppoints[i - 1]->y);
  }
  end = clock();
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("length %f time spent %f\n", path_length, time_spent);
  begin = clock();
  path_length = 0;
  for(i = 1; i < ARR_LEN; ++i){
    path_length += DIST(ppoints2[i]->x, ppoints2[i - 1]->x,
                        ppoints2[i]->y, ppoints2[i - 1]->y);
  }
  end = clock();
  time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  printf("length %f time spent %f\n", path_length, time_spent);
  return 0;
}

ne úplně umělý příklad. Výpočet délky cesty ze seznamu bodů. Na mém počítači je průchod points dvakrát rychlejší než průchod ppoints2 a asi o 50% rychlejší než ppoints. Uznávám, čekal jsem větší rozdíl.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: ava 20. 09. 2016, 08:44:33
Souhlasím, že pole structů by v Javě mohlo občas pomoci. Teďka implementuju kolaborativní filtr, který má v reálném čase ohodnotit uživatele podle toho, jak by se jim mohl líbit nějaký produkt, když se jim líbily podobné produkty, podobnost dvou produktů se pozná podle toho, že  byly často kupované spolu. Při výpočtu jde opravdu o rychlost za každou cenu. Po předělání z HashMap na Array a reorganizaci dat v paměti se výpočet zrychlil 200x bez faktické změny algoritmu.

Mám předpočítanou mapu podobností, která má cca 50 000 000 položek, konceptuálně jde o páry (uživatel: Int, podobnost: Float). Co s tím? Ideální by bylo mít jedno velké pole struktur (user, similarity), ale to v Javě nejde. Takže si buďto udělám dvě velké pole, jedno pouze s uživateli, druhé s podobnostmi, a budu je procházet souběžne (tím přijdu o jednu cache linku, což zrovna v tomto případě tolik nevadí), nebo budu mít jedno velké pole, a vždy lichý prvek bude uživatel, a na sudý udělám Float.intBitsToFloat/Float.floatToRawIntBits. Kdybych v tom poli měl reference na tuple (uživatel, podobnost), tak se to celé šíleně zpomalí kvůli dereferencím (šahání do paměti), a navíc to bude zabírat místo 400 MB (8 bajtů na položku) cca 1400 MB (kvůli headeru a alignmentu očekávám 24 bajtů na instanci tuplu + 4 bajty reference v poli) To celé jen kvůli tomu, že Java nemá struct.

Jak by se tohle implementovalo v nějaké databázi si nedovedu představit, hlavně jak ji donutit, aby si přes všechny databázové abstrakce zorganizovala data v paměti a použila algoritmus průchodu přesně tak, jak potřebuji.

Takže určitě jsou scénáře, kde by se structy hodily, i když to není nijak superčasté. Otázka je, jak hodně by to zkomplikovalo jazyk, docela by mě zajímalo, jestli to v C# nepřináší nějaké nečekané trable? Každopádně umět vhodně data zorganizovat v paměti je pro rychlé výpočty zásadní, přístup do hlavní paměti je dnes obrovskou brzdou.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: atarist 20. 09. 2016, 09:02:48
Souhlasím, že pole structů by v Javě mohlo občas pomoci. Teďka implementuju kolaborativní filtr, který má v reálném čase ohodnotit uživatele podle toho, jak by se jim mohl líbit nějaký produkt, když se jim líbily podobné produkty, podobnost dvou produktů se pozná podle toho, že  byly často kupované spolu. Při výpočtu jde opravdu o rychlost za každou cenu. Po předělání z HashMap na Array a reorganizaci dat v paměti se výpočet zrychlil 200x bez faktické změny algoritmu.

Mám předpočítanou mapu podobností, která má cca 50 000 000 položek, konceptuálně jde o páry (uživatel: Int, podobnost: Float). Co s tím? Ideální by bylo mít jedno velké pole struktur (user, similarity), ale to v Javě nejde. Takže si buďto udělám dvě velké pole, jedno pouze s uživateli, druhé s podobnostmi, a budu je procházet souběžne (tím přijdu o jednu cache linku, což zrovna v tomto případě tolik nevadí), nebo budu mít jedno velké pole, a vždy lichý prvek bude uživatel, a na sudý udělám Float.intBitsToFloat/Float.floatToRawIntBits. Kdybych v tom poli měl reference na tuple (uživatel, podobnost), tak se to celé šíleně zpomalí kvůli dereferencím (šahání do paměti), a navíc to bude zabírat místo 400 MB (8 bajtů na položku) cca 1400 MB (kvůli headeru a alignmentu očekávám 24 bajtů na instanci tuplu + 4 bajty reference v poli) To celé jen kvůli tomu, že Java nemá struct.

Jak by se tohle implementovalo v nějaké databázi si nedovedu představit, hlavně jak ji donutit, aby si přes všechny databázové abstrakce zorganizovala data v paměti a použila algoritmus průchodu přesně tak, jak potřebuji.

Takže určitě jsou scénáře, kde by se structy hodily, i když to není nijak superčasté. Otázka je, jak hodně by to zkomplikovalo jazyk, docela by mě zajímalo, jestli to v C# nepřináší nějaké nečekané trable? Každopádně umět vhodně data zorganizovat v paměti je pro rychlé výpočty zásadní, přístup do hlavní paměti je dnes obrovskou brzdou.

Teoreticky pokud to neni extra ridke pole muze byt index == (ID_uzivatele - nejaky_offset) + nejaky NaN pro neexistujici ID_uzivatele ale to skutecne zalezi na datech, nekdy to jde, nekdy ne. Usetris tedy v idealnim pripade 50% dat (i cache!), v neidealnim pripade budes mit ridke pole floatu...

OT: prosim snaz se to naprogramovat inteligentne a ne tak, ze kdyz si koupim kolo, tak se ma dalsich x mesicu objevuje reklama na dalsi kola. Docela bych rekl ze jezdit a opravovat kolo umim, takze par desitek tisic kilometru vydrzi, nebudu kupovat dalsi :) takze by me reklama zahackovala na spotrebak (plaste, retezy...).
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: ava 20. 09. 2016, 09:21:37
Teoreticky pokud to neni extra ridke pole muze byt index == (ID_uzivatele - nejaky_offset) + nejaky NaN pro neexistujici ID_uzivatele ale to skutecne zalezi na datech, nekdy to jde, nekdy ne. Usetris tedy v idealnim pripade 50% dat (i cache!), v neidealnim pripade budes mit ridke pole floatu...

OT: prosim snaz se to naprogramovat inteligentne a ne tak, ze kdyz si koupim kolo, tak se ma dalsich x mesicu objevuje reklama na dalsi kola. Docela bych rekl ze jezdit a opravovat kolo umim, takze par desitek tisic kilometru vydrzi, nebudu kupovat dalsi :) takze by me reklama zahackovala na spotrebak (plaste, retezy...).

Vynechal jsem nějaké detaily, tohle pole už je tak husté jak je to možné, nejsou tam položky s nulovou similaritou, uživatelé co nic nekoupili atp., to už je všechno vyoptimalizované.

Co se týče OT, jasně, snažíme se, tvoje reklama bude tak super, že už ani nebudeš mít čas na kole jezdit, budeš jen nakupovat nejlepší spotřebák :)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: atarist 20. 09. 2016, 09:57:31
OT: prosim snaz se to naprogramovat inteligentne a ne tak, ze kdyz si koupim kolo, tak se ma dalsich x mesicu objevuje reklama na dalsi kola. Docela bych rekl ze jezdit a opravovat kolo umim, takze par desitek tisic kilometru vydrzi, nebudu kupovat dalsi :) takze by me reklama zahackovala na spotrebak (plaste, retezy...).
Co se týče OT, jasně, snažíme se, tvoje reklama bude tak super, že už ani nebudeš mít čas na kole jezdit, budeš jen nakupovat nejlepší spotřebák :)

Hehe super, konecne pozitivni zprava na diskuzich na rootu. cekam s kreditkou v ruce... :)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Kolemjdoucí 20. 09. 2016, 10:57:10
Zkus si porovnat rychlost průchodu dlouhého pole.
Porovnat s čím? A co znamená „průchod pole“?

Diskuse se točí dokola, Jirsák odmítá uznat naprosto elementární fakta. Konkrétní příklady procházení pole jsem jsem popisoval už v příspěvku #32.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 11:47:40
Diskuse se točí dokola, Jirsák odmítá uznat naprosto elementární fakta. Konkrétní příklady procházení pole jsem jsem popisoval už v příspěvku #32.
Elementární fakta já uznávám. První, kdo sem nějaká fakta napsal, byl gl, a potvrdil, co tady celou dobu píšu:

Na mém počítači je průchod points dvakrát rychlejší než průchod ppoints2 a asi o 50% rychlejší než ppoints. Uznávám, čekal jsem větší rozdíl.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: podlesh 20. 09. 2016, 12:07:09
Mám předpočítanou mapu podobností, která má cca 50 000 000 položek, konceptuálně jde o páry (uživatel: Int, podobnost: Float). Co s tím? Ideální by bylo mít jedno velké pole struktur (user, similarity), ale to v Javě nejde. Takže si buďto udělám dvě velké pole, jedno pouze s uživateli, druhé s podobnostmi, a budu je procházet souběžne (tím přijdu o jednu cache linku, což zrovna v tomto případě tolik nevadí),...
Jenom technická: takto se to implementuje prakticky všude (např. Python), protože se pak používají vektorové a maticové operace. Ty jsou extrémně rychlé nejenom kvůli nativní implementaci (tj. v C, Fortranu nebo dokonce asm), ale také kvůli tomu že je optimalizovali matematici :-)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gamer 20. 09. 2016, 12:40:05
ne úplně umělý příklad. Výpočet délky cesty ze seznamu bodů. Na mém počítači je průchod points dvakrát rychlejší než průchod ppoints2 a asi o 50% rychlejší než ppoints. Uznávám, čekal jsem větší rozdíl.

Ten test je značně syntetický, normálně objekty vznikají v různém čase a nejsou v paměti za sebou. Tato úprava ho trochu zreální:
Kód: [Vybrat]
@@ -28,7 +28,7 @@ int main()
   for(i = 0; i < ARR_LEN; ++i){
     points[i].x = rand() % 20;
     points[i].y = rand() % 20;
-    ppoints[i] = &points[i];
+    ppoints[i] = &points[rand() % ARR_LEN];
     ppoints2[i]->x = points[i].x;
     ppoints2[i]->y = points[i].y;
   }

Což je u mě (po zvětšení ARR_LEN) skoro 6x pomalejší:
Kód: [Vybrat]
length 1041522432.408077 time spent 0.760000
length 1041511428.008295 time spent 4.350000
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 13:29:50
ne úplně umělý příklad. Výpočet délky cesty ze seznamu bodů. Na mém počítači je průchod points dvakrát rychlejší než průchod ppoints2 a asi o 50% rychlejší než ppoints. Uznávám, čekal jsem větší rozdíl.

Ten test je značně syntetický, normálně objekty vznikají v různém čase a nejsou v paměti za sebou. Tato úprava ho trochu zreální:
Kód: [Vybrat]
@@ -28,7 +28,7 @@ int main()
   for(i = 0; i < ARR_LEN; ++i){
     points[i].x = rand() % 20;
     points[i].y = rand() % 20;
-    ppoints[i] = &points[i];
+    ppoints[i] = &points[rand() % ARR_LEN];
     ppoints2[i]->x = points[i].x;
     ppoints2[i]->y = points[i].y;
   }

Což je u mě (po zvětšení ARR_LEN) skoro 6x pomalejší:
Kód: [Vybrat]
length 1041522432.408077 time spent 0.760000
length 1041511428.008295 time spent 4.350000

Snažil jsem se alokovat ppoints2 současně od konce a od začátku, ale asi to nepomohlo. ppoints mělo být pro srovnání za sebou.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 15:22:43
Ten test je značně syntetický, normálně objekty vznikají v různém čase a nejsou v paměti za sebou.
Ten test má porovnávat použití pole struktur a pole referencí. Pole struktur, které vznikají v různém čase, je velmi netypické použití. A pole struktur, které nejsou v paměti za sebou, není pole struktur. Pokud chcete porovnávat kód, kde objekty vznikají v různém čase a nejsou v paměti za sebou, zařaďte do testu i to, že ty struktury musíte do toho pole nejprve zkopírovat. A když už budete v tom testování, doporučuju změřit i paměťovou náročnost.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gamer 20. 09. 2016, 16:11:29
Ten test má porovnávat použití pole struktur a pole referencí. Pole struktur, které vznikají v různém čase, je velmi netypické použití. A pole struktur, které nejsou v paměti za sebou, není pole struktur. Pokud chcete porovnávat kód, kde objekty vznikají v různém čase a nejsou v paměti za sebou, zařaďte do testu i to, že ty struktury musíte do toho pole nejprve zkopírovat. A když už budete v tom testování, doporučuju změřit i paměťovou náročnost.

Bohužel to pořád nechápete. V Javě NEJDE zaručit, že se alokátor bude chovat inkrementálně a objekty bude umísťovat za sebe. Defaultně se o to snaží, ale ne vždy to lze. Problém je to hlavně při fragmentaci haldy, pak si alokátor bude vytvářet objekty tam, kde je zrovna místo. Nelze to rozumně ovlivnit. Heap compaction nic moc neřeší, protože je to drahé.

Takže i když v Javě objekty vytvářím postupně, můžou být rozházené kdekoliv po fyzické paměti. V syntetickém testu se to neprojeví, protože na začátku je halda prázdná a všechno funguje hezky. Projeví se to až po delším běhu, kdy už je halda fragmentovaná.

Jsou lidé, kteří chtějí, aby ty objekty byly v paměti za sebou, protože vědí, že je budou sekvenčně procházet. Normálně se to řeší tak, že se vytvoří pole objektů (nikoliv pole referencí), což ale v Javě AFAIK nejde udělat.

Takže nemá žádný smysl porovnávat přístup přes pointer nebo přes index do pole, v tom není významý rozdíl. Problém nastane až s fragmentovanou pamětí, protože v Javě neovlivním, kde ten objekt bude v paměti fyzicky vytvořen.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 16:11:51
Ten test je značně syntetický, normálně objekty vznikají v různém čase a nejsou v paměti za sebou.
Ten test má porovnávat použití pole struktur a pole referencí. Pole struktur, které vznikají v různém čase, je velmi netypické použití. A pole struktur, které nejsou v paměti za sebou, není pole struktur. Pokud chcete porovnávat kód, kde objekty vznikají v různém čase a nejsou v paměti za sebou, zařaďte do testu i to, že ty struktury musíte do toho pole nejprve zkopírovat. A když už budete v tom testování, doporučuju změřit i paměťovou náročnost.

points - pole struktur

ppoints - pole ukazatelů na struktury, které jsou v paměti za sebou

ppoints2 - pole ukazatelů na struktury, které nejsou v paměti za sebou.


paměťovou náročnost měřit nemusím. Ta je jasná.

Pokud změním pořadí alokování na

Kód: [Vybrat]
for(int i = 0; i < ARR_LEN; ++i){
    int index = (STEP_LEN * i) % ARR_LEN + (STEP_LEN * i)/ARR_LEN;
    ppoints2[index] = malloc(sizeof(struct Point));
  }

kde STEP_LEN dělí ARR_LEN, dostanu větší rozdíl v rychlosti.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 16:35:12
zařaďte do testu i to, že ty struktury musíte do toho pole nejprve zkopírovat.

Nic kopírovat nemusím. Naopak inicializace je mnohem rychlejší. Tam je ještě větší rozdíl než v průchodu. Nemusím alokovat paměť pro každou položku zvlášť.

Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 16:38:55
V Javě NEJDE zaručit, že se alokátor bude chovat inkrementálně a objekty bude umísťovat za sebe.
Když to bude pro výkon aplikace kritické, tak ta data (ne objekty) za sebe dám i v Javě. Klíčová je ta informace, že to v drtivé většině případů není důležité.

Jsou lidé, kteří chtějí, aby ty objekty byly v paměti za sebou, protože vědí, že je budou sekvenčně procházet.
Ano, tohle je problém. Že si někteří lidé myslí, že vědí, jak funguje procesor, a snaží se program neuměle předem optimalizovat. V lepším případě to dopadne tak, že na výkonu nic nepokazí a jenom znepřehlední kód. V horším případě kód zkomplikují i pro procesor, takže ten „optimalizovaný“ program bude pomalejší, než neoptimalizovaný. A pak je hrstka těch programátorů, kteří dokážou změřit, kdy je potřeba kód opravdu optimalizovat, a opravdu ho zoptimalizují (což opět prokážou měřením). Přičemž ten program může být napsaný v libovolném jazyce.

Normálně se to řeší tak, že se vytvoří pole objektů (nikoliv pole referencí), což ale v Javě AFAIK nejde udělat.
V Javě se to vyřeší například polem primitivních typů.

Problém nastane až s fragmentovanou pamětí, protože v Javě neovlivním, kde ten objekt bude v paměti fyzicky vytvořen.
Což je dobře, protože problém ve skutečnosti nastane už v okamžiku, kdy to někdo začne „optimalizovat“.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 16:41:25
Nic kopírovat nemusím. Naopak inicializace je mnohem rychlejší. Tam je ještě větší rozdíl než v průchodu. Nemusím alokovat paměť pro každou položku zvlášť.
Nevytrhávejte věty z kontextu. O kopírování jsem psal v případě, kdy ty struktury vznikají v aplikaci v různém čase.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gamer 20. 09. 2016, 16:48:15
Když to bude pro výkon aplikace kritické, tak ta data (ne objekty) za sebe dám i v Javě. Klíčová je ta informace, že to v drtivé většině případů není důležité.
Jak to v Javě udělám? Drtivá většina je co? Drtivá většina aplikací Filipa Jirsáka?

Ano, tohle je problém. Že si někteří lidé myslí, že vědí, jak funguje procesor, a snaží se program neuměle předem optimalizovat.
Jste úplně vedle, s procesorem to vůbec nesouvisí. Jde o PAMĚŤ, protože pamět je násobně pomalejší než procesor. Jak funguje paměť je všeobecně známé, je mnohem rychlejší při sekvenčním čtení dat. Pokud mám velká data, vždy je výhodnější je mít v paměti za sebou. Není v tom žádná magie, je to úplně jednoduchý princip. Pokud nevíte, jak funguje pamět, tak raději zůstaňte u Javy, tam to ovlivnit nejde a budete spokojen.

V Javě se to vyřeší například polem primitivních typů.
Já ale nechci primitivní typy, chci normální objekty, proč bych to měl nějak hackovat?

Problém nastane až s fragmentovanou pamětí, protože v Javě neovlivním, kde ten objekt bude v paměti fyzicky vytvořen.
Což je dobře, protože problém ve skutečnosti nastane už v okamžiku, kdy to někdo začne „optimalizovat“.
Cože???
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: lol 20. 09. 2016, 17:28:02
Citace
Cože???

To zřejmě mělo znamenat, že když programujete v jazyce, který si spravuje paměť sám, tak byste to měl akceptovat a přestat z toho dělat nějaké pseudocéčko. Jestli se přes to přenést nedokážete, tak prostě programujte v céčku. Simple as that.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gamer 20. 09. 2016, 17:34:56
To zřejmě mělo znamenat, že když programujete v jazyce, který si spravuje paměť sám, tak byste to měl akceptovat a přestat z toho dělat nějaké pseudocéčko. Jestli se přes to přenést nedokážete, tak prostě programujte v céčku. Simple as that.

Nikdo z toho C dělat nechce, od začátku jde o to, že v Javě nejde udělat pole objektů. Nevidím žádný principielní problém, proč by se to s garbage collectorem udělat nedalo, prostě to tam není. Java evangelisti to hájí tak, že to vlastně není potřeba a nikdo to nechce a má se místo toho používat pole referencí.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Ondra Satai Nekola 20. 09. 2016, 17:35:31
Zrovna nedavno:

http://funkcionalne.cz/2016/09/mytus-o-o1-pameti/
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 18:02:06
Java evangelisti to hájí tak, že to vlastně není potřeba a nikdo to nechce a má se místo toho používat pole referencí.

Podle Java evangelistů není potřeba žádná featura, kterou Java neumí. Stejně v minulosti obhajovali neexistenci generik a lambda funkcí. Až vyjde Java 10, tak  změní názor a budou hodnotové typy cpát všude.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 18:03:48
Jak to v Javě udělám?
Především analyzuju, co ta příslušná část programu řeší, a budu se snažit najít nějaké jiné řešení. Nejčastěji to povede na jinou strukturu dat, možná jiný algoritmus. Pokud to náhodou bude ten výjimečný případ, kdy je potřeba mít data v paměti za sebou, uložím to třeba jako pole intů nebo bajtů.

Drtivá většina je co?
Drtivá většina je 99 % všech aplikací.

Jste úplně vedle, s procesorem to vůbec nesouvisí. Jde o PAMĚŤ, protože pamět je násobně pomalejší než procesor. Jak funguje paměť je všeobecně známé, je mnohem rychlejší při sekvenčním čtení dat. Pokud mám velká data, vždy je výhodnější je mít v paměti za sebou. Není v tom žádná magie, je to úplně jednoduchý princip. Pokud nevíte, jak funguje pamět, tak raději zůstaňte u Javy, tam to ovlivnit nejde a budete spokojen.
Nejvíce škod na výkonu aplikací napáchají programátoři, kteří pořád něco optimalizují, protože si myslí, že vědí, jak funguje paměť a procesor – myslí si, že přístup do paměti je O(1), pod přístupem do paměti si představují reálný režim i386 a to, že přístup do paměti mapuje runtime knihovna, operační systém i virtuální počítač zanedbávají, a optimalizují pro počítač s jedním procesorem a jedním vláknem, které provádí instrukce pěkně za sebou jak jsou ve spustitelném kódu.

Já ale nechci primitivní typy, chci normální objekty, proč bych to měl nějak hackovat?
Protože jste zjistil, že je to výkonově kritické místo vaší aplikace, a bez hackování to optimalizovat nejde. To je dost dobrý důvod pro hackování. Rozhodně mnohem lepší, než „tady to určitě bude pomalé, tak to nahackuju preventivně“.

Cože???
No jak je vidět i na této diskusi, do preventivních optimalizací se pouštějí především programátoři, kteří moc netuší, jak vypadá běh programu v moderním systému. Takže „optimalizují“ části programu, které to vůbec nepotřebují, „optimalizují“ tím, že hlavně znepřehlední kód, a občas ho pokazí tak, že už si s tím nic nezmůže ani kompilátor ani CPU, protože musí provádět ty nesmysly, které tam programátor při „optimalizaci“ napsal. Co se týče kvality výstupu, jsou na tom stejně, jako programátoři, kteří bez přemýšlení napíšou nějaký na první pohled nesmyslně zdlouhavý algoritmus, ale „optimalizátoři“ jsou proti nim nebezpečnější, protože si zpravidla nenechají vysvětlit, že dělají hlouposti.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gamer 20. 09. 2016, 20:48:43
Už mě to moc nebaví, takže jenom krátce.

Vytvoření pole objektů není žádná optimalizace, je to přímočarý nativní přístup.

Vytvoření pole referencí na objekty je javovina, nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální. Většinou ta neoptimálnost nevadí, pokud ano, je to v Javě problém, protože to nejde normálně vyřešit, musí se to hackovat přes pole primitivních typů, což úplně rozbije datový model a kód v aplikaci.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 21:14:36
Vytvoření pole referencí na objekty je javovina
A taky C++ovina, C#ovina, Pythonovina, JavaScriptovina, PHPovina atd. „Nativní“ je to možná tak v C.

nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální
Co se týče přístupu do paměti, je neoptimální pole objektů. Musíte předem vědět, jak je velké, jak velké jsou objekty, rezervovat místo na největší možný objekt, když s ním chcete něco dělat (filtrovat, řadit), musíte kopírovat celé objekty.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Abych pravdu řekl, pořád vám nevěřím, že máte opravdu takovou hrůzu z referencí. Myslím si, že ve skutečnosti reference normálně používáte, akorát to nechcete přiznat, protože pak byste najednou musel vysvětlovat, proč jsou reference někdy dobré, ale jakmile jde o pole, jsou špatné. Protože jestli seznam 1000 osob, z nichž každá může mít jméno, prostřední jméno, příjmení a rodné příjmení, každé po 100 znacích, opravdu vytváříte tak, že alokujete 400 kB, jenom abyste se vyhnul referencím, a říkáte tomu optimální využití paměti…
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: v 20. 09. 2016, 21:16:52
Vytvoření pole referencí na objekty je javovina
A taky C++ovina, C#ovina, Pythonovina, JavaScriptovina, PHPovina atd. „Nativní“ je to možná tak v C.

nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální
Co se týče přístupu do paměti, je neoptimální pole objektů. Musíte předem vědět, jak je velké, jak velké jsou objekty, rezervovat místo na největší možný objekt, když s ním chcete něco dělat (filtrovat, řadit), musíte kopírovat celé objekty.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Abych pravdu řekl, pořád vám nevěřím, že máte opravdu takovou hrůzu z referencí. Myslím si, že ve skutečnosti reference normálně používáte, akorát to nechcete přiznat, protože pak byste najednou musel vysvětlovat, proč jsou reference někdy dobré, ale jakmile jde o pole, jsou špatné. Protože jestli seznam 1000 osob, z nichž každá může mít jméno, prostřední jméno, příjmení a rodné příjmení, každé po 100 znacích, opravdu vytváříte tak, že alokujete 400 kB, jenom abyste se vyhnul referencím, a říkáte tomu optimální využití paměti…
s váma je legrace :)
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 21:37:08
Vytvoření pole referencí na objekty je javovina
A taky C++ovina, C#ovina, Pythonovina, JavaScriptovina, PHPovina atd. „Nativní“ je to možná tak v C.

nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální
Co se týče přístupu do paměti, je neoptimální pole objektů. Musíte předem vědět, jak je velké, jak velké jsou objekty, rezervovat místo na největší možný objekt, když s ním chcete něco dělat (filtrovat, řadit), musíte kopírovat celé objekty.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Abych pravdu řekl, pořád vám nevěřím, že máte opravdu takovou hrůzu z referencí. Myslím si, že ve skutečnosti reference normálně používáte, akorát to nechcete přiznat, protože pak byste najednou musel vysvětlovat, proč jsou reference někdy dobré, ale jakmile jde o pole, jsou špatné. Protože jestli seznam 1000 osob, z nichž každá může mít jméno, prostřední jméno, příjmení a rodné příjmení, každé po 100 znacích, opravdu vytváříte tak, že alokujete 400 kB, jenom abyste se vyhnul referencím, a říkáte tomu optimální využití paměti…

Tady nikdo hrůzu z referencí nemá. Ve většině případů je jejich použití asi optimální. Já programuji jen ve skriptovacích jazycích kde podobné optimalizace dělat nejdou a nikdy jsem je nepotřeboval. Reagoval jsem jen na tvrzení, že pole referencí je stejně efektivní jako pole pole hodnot.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 20. 09. 2016, 21:47:36
Reagoval jsem jen na tvrzení, že pole referencí je stejně efektivní jako pole pole hodnot.
Což tady pokud vím nikdo netvrdil. Už jenom proto, že jsou různá hlediska efektivity, která jdou často proti sobě. A také různé způsoby použití.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Vladimír Drgoňa 20. 09. 2016, 22:34:57
Už mě to moc nebaví, takže jenom krátce.

Vytvoření pole objektů není žádná optimalizace, je to přímočarý nativní přístup.

Vytvoření pole referencí na objekty je javovina, nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální. Většinou ta neoptimálnost nevadí, pokud ano, je to v Javě problém, protože to nejde normálně vyřešit, musí se to hackovat přes pole primitivních typů, což úplně rozbije datový model a kód v aplikaci.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Tak toto je absolútna <|>vina. Referencie aj objekty sú v Random Access Memory, t.j. v pamäti s ľubovoľným prístupom. Moderné operačné systémy používajú virtuálnu adresáciu pamäte a nikto nezaručí, že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde. Samozrejme platí, že pre procesor sú dáta najrýchlejšie prístupné v poradí register -> L1 -> L2 -> L3 -> RAM -> SWAP. Platí že je vyššia pravdepodobnosť, že pole hodnôt bude bližšie k procesoru (L1, L2,L3) ako keď pôjde o pole referencií, čím by výpočet teoreticky mohol prebehnúť rýchlejšie.
Keďže ale na serveri beží paralelne oveľa viac procesov ako je jadier procesorov, (na mojom serveri je to napríklad teraz 4 jadrá/211 procesov), procesy sa na jednom jadre prepínajú (o to sa stará OS), L1,L2 a L3 sa vyprázdňuje a načítava podľa potreby procesov (o to sa stará správca cache v procesore), pravdepodobnosť toho, že pole hodnôt zostane v cache počas celej práce s poľom je takmer nulová a celá snaha o takúto optimalizáciu nemá žiaden zmysel.
Oveľa väčší zmysel ako sa snažiť o ušetrenie pár nanosekúnd v prístupe k RAM je venovať sa problému, analyzovať ho, zjednodušiť a skrátiť a zrýchliť tým výpočet.
Z celej tejto diskusie mi vyplýva, že pri programovaní v C# sa musí hlavne všetko optimalizovať (keďže to nezvládne za neho OS) a celý jazyk je ako trošku lepší assembler, kdežto v Jave sa sústredím na problém a vyriešim ho tým oveľa rýchlejšie, priamočiarejšie a keďže pri tom nemusím používať všelijaké hacky, tak aj prehľadnejšie pre ostatných.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Radek Miček 20. 09. 2016, 23:00:38
Už mě to moc nebaví, takže jenom krátce.

Vytvoření pole objektů není žádná optimalizace, je to přímočarý nativní přístup.

Vytvoření pole referencí na objekty je javovina, nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální. Většinou ta neoptimálnost nevadí, pokud ano, je to v Javě problém, protože to nejde normálně vyřešit, musí se to hackovat přes pole primitivních typů, což úplně rozbije datový model a kód v aplikaci.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde.

To je pravda, ale stále bude velké množství hodnot u sebe.

Zatímco, když použijete pole referencí, tak zvyšujete spotřebu paměti (v mém příkladu se zvýšila 6x) - což mj. znamená, že plýtváte cachí. Dále zvyšujete počet alokovaných objektů, jejichž dosažitelnost bude GC periodicky kontrolovat (je-li délka pole n, počet objektů se zvýší cca n krát) - tj. zbytečná zátěž pro CPU. A nakonec je tu větší riziko, že hodnoty nebudou u sebe.

Pro připomenutí můj příklad:

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 4040 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).

kdežto v Jave sa sústredím na problém a vyriešim ho tým oveľa rýchlejšie, priamočiarejšie a keďže pri tom nemusím používať všelijaké hacky, tak aj prehľadnejšie pre ostatných.

A proč se to tedy plánuje přidat do Javy?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: atarist 20. 09. 2016, 23:00:49
Tak toto je absolútna <|>vina. Referencie aj objekty sú v Random Access Memory, t.j. v pamäti s ľubovoľným prístupom. Moderné operačné systémy používajú virtuálnu adresáciu pamäte a nikto nezaručí, že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde. Samozrejme platí, že pre procesor sú dáta najrýchlejšie prístupné v poradí register -> L1 ->

Asi vím, jaks to myslel, ale to co jsi napsal není pravda. Paměť není "RAM" (v původním významu toho slova) asi tak 25 let, stejně jako SSD není žádný disk :-) Podívej, jak je organizovaná L1 a L2 cache, jak dlouhé jsou cache line a zejména kolik jich je. To je omezující faktor, který se každou další dereferencí zhoršuje a zhoršuje, což je snadno měřitelné. Ano, nikdo nezaručí, že přečteš 100 MB pole tak, že budeš mít vše dopředu v cache, ale co bude u pole struktur/primitivních hodnot zaručeno je, že jak se určitý prvek dostane do cache line, budou tam i ty následující prvky. U pole referencí máš jen jistotu, že čtení dalších N referencí (ne hodnot!) bude možná v cache, možná ale taky ne, protože se to přeplácne načítanými strukturami.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: zboj 20. 09. 2016, 23:01:08
Už mě to moc nebaví, takže jenom krátce.

Vytvoření pole objektů není žádná optimalizace, je to přímočarý nativní přístup.

Vytvoření pole referencí na objekty je javovina, nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální. Většinou ta neoptimálnost nevadí, pokud ano, je to v Javě problém, protože to nejde normálně vyřešit, musí se to hackovat přes pole primitivních typů, což úplně rozbije datový model a kód v aplikaci.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Tak toto je absolútna <|>vina. Referencie aj objekty sú v Random Access Memory, t.j. v pamäti s ľubovoľným prístupom. Moderné operačné systémy používajú virtuálnu adresáciu pamäte a nikto nezaručí, že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde. Samozrejme platí, že pre procesor sú dáta najrýchlejšie prístupné v poradí register -> L1 -> L2 -> L3 -> RAM -> SWAP. Platí že je vyššia pravdepodobnosť, že pole hodnôt bude bližšie k procesoru (L1, L2,L3) ako keď pôjde o pole referencií, čím by výpočet teoreticky mohol prebehnúť rýchlejšie.
Keďže ale na serveri beží paralelne oveľa viac procesov ako je jadier procesorov, (na mojom serveri je to napríklad teraz 4 jadrá/211 procesov), procesy sa na jednom jadre prepínajú (o to sa stará OS), L1,L2 a L3 sa vyprázdňuje a načítava podľa potreby procesov (o to sa stará správca cache v procesore), pravdepodobnosť toho, že pole hodnôt zostane v cache počas celej práce s poľom je takmer nulová a celá snaha o takúto optimalizáciu nemá žiaden zmysel.
Oveľa väčší zmysel ako sa snažiť o ušetrenie pár nanosekúnd v prístupe k RAM je venovať sa problému, analyzovať ho, zjednodušiť a skrátiť a zrýchliť tým výpočet.
Z celej tejto diskusie mi vyplýva, že pri programovaní v C# sa musí hlavne všetko optimalizovať (keďže to nezvládne za neho OS) a celý jazyk je ako trošku lepší assembler, kdežto v Jave sa sústredím na problém a vyriešim ho tým oveľa rýchlejšie, priamočiarejšie a keďže pri tom nemusím používať všelijaké hacky, tak aj prehľadnejšie pre ostatných.
Celá diskuse začala tím, že R. Miček tvrdil, že Java zbytečně zatíží GC, protože nemá hodnotové typy, na rozdíl od C#, ve kterém to tedy bude efektivnější paměťově (ušetří se práce GC). Což je bezezbytku pravda. Zbytek jsou jen žvásty, co se nabalily jako sněhová koule na zpočátku věcnou a užitečnou radu.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: gl 20. 09. 2016, 23:45:18
Už mě to moc nebaví, takže jenom krátce.

Vytvoření pole objektů není žádná optimalizace, je to přímočarý nativní přístup.

Vytvoření pole referencí na objekty je javovina, nic to nepřináší (kromě zjednodušení garbage collectoru), co se týká přístupu do paměti je to neoptimální. Většinou ta neoptimálnost nevadí, pokud ano, je to v Javě problém, protože to nejde normálně vyřešit, musí se to hackovat přes pole primitivních typů, což úplně rozbije datový model a kód v aplikaci.

Nazývat převedení pole referencí na pole objektů předčasnou optimalizací je úplně mimo, pole objektů by měl být nativní přístup, ale není, protože Java...
Tak toto je absolútna <|>vina. Referencie aj objekty sú v Random Access Memory, t.j. v pamäti s ľubovoľným prístupom. Moderné operačné systémy používajú virtuálnu adresáciu pamäte a nikto nezaručí, že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde. Samozrejme platí, že pre procesor sú dáta najrýchlejšie prístupné v poradí register -> L1 -> L2 -> L3 -> RAM -> SWAP. Platí že je vyššia pravdepodobnosť, že pole hodnôt bude bližšie k procesoru (L1, L2,L3) ako keď pôjde o pole referencií, čím by výpočet teoreticky mohol prebehnúť rýchlejšie.
Keďže ale na serveri beží paralelne oveľa viac procesov ako je jadier procesorov, (na mojom serveri je to napríklad teraz 4 jadrá/211 procesov), procesy sa na jednom jadre prepínajú (o to sa stará OS), L1,L2 a L3 sa vyprázdňuje a načítava podľa potreby procesov (o to sa stará správca cache v procesore), pravdepodobnosť toho, že pole hodnôt zostane v cache počas celej práce s poľom je takmer nulová a celá snaha o takúto optimalizáciu nemá žiaden zmysel.
Oveľa väčší zmysel ako sa snažiť o ušetrenie pár nanosekúnd v prístupe k RAM je venovať sa problému, analyzovať ho, zjednodušiť a skrátiť a zrýchliť tým výpočet.
Z celej tejto diskusie mi vyplýva, že pri programovaní v C# sa musí hlavne všetko optimalizovať (keďže to nezvládne za neho OS) a celý jazyk je ako trošku lepší assembler, kdežto v Jave sa sústredím na problém a vyriešim ho tým oveľa rýchlejšie, priamočiarejšie a keďže pri tom nemusím používať všelijaké hacky, tak aj prehľadnejšie pre ostatných.

Naměřil jsem víc než dvojnásobný rozdíl v rychlosti průchodu polem pro různá pořadí alokace prvků. To chceš vysvětlit jak?
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 21. 09. 2016, 06:58:54
To je pravda, ale stále bude velké množství hodnot u sebe.
To je zajímavé, že tohle nepovažujete za platný argument, ale jakmile se vám to hodí, použijete ho také.

Zatímco, když použijete pole referencí, tak zvyšujete spotřebu paměti (v mém příkladu se zvýšila 6x)
To je nesmyslný údaj, zvýšení spotřeby paměti záleží na ukládaných datech a může to být jakékoli kladné racionální číslo.

což mj. znamená, že plýtváte cachí
Neznamená. To je pouze vaše tvrzení plynoucí z toho, že pravděpodobně nevíte, jak moderní CPU pracují.

Dále zvyšujete počet alokovaných objektů, jejichž dosažitelnost bude GC periodicky kontrolovat (je-li délka pole n, počet objektů se zvýší cca n krát) - tj. zbytečná zátěž pro CPU.
Takže na ty vaše objekty v poli se nedá udělat reference? To je ale děsivé omezení a jakýkoli algoritmus, který s tím naprogramujete, je neefektivní…

A proč se to tedy plánuje přidat do Javy?
Protože to tam není.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: Filip Jirsák 21. 09. 2016, 07:07:17
Asi vím, jaks to myslel, ale to co jsi napsal není pravda. Paměť není "RAM" (v původním významu toho slova) asi tak 25 let, stejně jako SSD není žádný disk :-) Podívej, jak je organizovaná L1 a L2 cache, jak dlouhé jsou cache line a zejména kolik jich je. To je omezující faktor, který se každou další dereferencí zhoršuje a zhoršuje, což je snadno měřitelné. Ano, nikdo nezaručí, že přečteš 100 MB pole tak, že budeš mít vše dopředu v cache, ale co bude u pole struktur/primitivních hodnot zaručeno je, že jak se určitý prvek dostane do cache line, budou tam i ty následující prvky. U pole referencí máš jen jistotu, že čtení dalších N referencí (ne hodnot!) bude možná v cache, možná ale taky ne, protože se to přeplácne načítanými strukturami.
Problém vašeho tvrzení je v tom, že ani CPU nevypadá stejně, jako před 25 lety, a neběží na něm jediná úloha, jako před 25 lety.

To měření tady někdo provedl, a zjistil zhoršení o 100 % a o 50 %. Což je něco, čím se normálně není potřeba zabývat.

Navíc většina těch příkladů, které se tady uvádí, se na moderních CPU dá mnohem více optimalizovat tím, že se budou provádět paralelně.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: tisnik 21. 09. 2016, 09:59:25
Asi vím, jaks to myslel, ale to co jsi napsal není pravda. Paměť není "RAM" (v původním významu toho slova) asi tak 25 let, stejně jako SSD není žádný disk :-) Podívej, jak je organizovaná L1 a L2 cache, jak dlouhé jsou cache line a zejména kolik jich je. To je omezující faktor, který se každou další dereferencí zhoršuje a zhoršuje, což je snadno měřitelné. Ano, nikdo nezaručí, že přečteš 100 MB pole tak, že budeš mít vše dopředu v cache, ale co bude u pole struktur/primitivních hodnot zaručeno je, že jak se určitý prvek dostane do cache line, budou tam i ty následující prvky. U pole referencí máš jen jistotu, že čtení dalších N referencí (ne hodnot!) bude možná v cache, možná ale taky ne, protože se to přeplácne načítanými strukturami.
Problém vašeho tvrzení je v tom, že ani CPU nevypadá stejně, jako před 25 lety, a neběží na něm jediná úloha, jako před 25 lety.

To měření tady někdo provedl, a zjistil zhoršení o 100 % a o 50 %. Což je něco, čím se normálně není potřeba zabývat.

Navíc většina těch příkladů, které se tady uvádí, se na moderních CPU dá mnohem více optimalizovat tím, že se budou provádět paralelně.

Souhlas s tim, ze pro vetsinu aplikaci je lepsi, rychlejsi a jaksi prijemnejsi zmena algoritmu nez resit tyto optimalizace (prvni a zasadni optimalizaci je vyber jazyka vhodneho pro danou ulohu a vime, ze to neni snadne z mnoha technologickych i politickych duvodu).

Ad CPU: to je skutecne pravda, ovsem to v tomto kontextu neni az tak relevantni. Dulezitejsi je organizace cache (tu zname) a take to, co se stane v tom horsim pripade, kdy se musi sahat do operacni pameti (RAM). Kdysi - a lidi asi maji nekdy pocit, ze to stale plati - byl cip s SRAM docela jednoduchy, proste se poslala adresa, nastavil se R/W bit a po par taktech se cetlo/zapisovalo. Ostatne CPU byly rychlosti srovnatelny s SRAM, takze dokonce bylo mozne, ze dokud CPU pocital, pristupovala k SRAM jina periferie.

Ale uz DRAM mely rozdeleni CAS/RAS, takze cteni 'radku' je mnohem rychlejsi nez neustale vystavovani jak RAS tak CAS. S SDRAM a burst rezimem je to jeste o obrovsky krok dale a nahodne cteni je strasne drahe (doporucuji se podivat na ten prenosovy protokol) kdezto cteni/zapis cele cache line (64 bajtu atd.) je mnohem rychlejsi. Tudiz nezavisle na CPU proste plati, ze kontinualni pristup do pameti je rychlejsi, klidne i radove.

A ze v CPU bezi vic vlaken? Skutecne ano, ale pokud dochazi k invalidaci vsech cache line po prepnuti vlakna, znamena to s velkou pravdepodobnosti, ze to dalsi vlakno pouzivalo nahodny pristup a za tu chvili behu rozdrbalo zbytek 'systemu' (tedy je to komplikovanejsi diky lokalite L1 a vetsinou globalite L2).

Opakuji - v naproste vetsine pripadu to clovek nemusi az tak moc brat v uvahu, ale reakce na nazor "RAM je random access" musela zaznit, protoze to neni a uz asi nikdy nebude pravda.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: NooN 21. 09. 2016, 10:39:22
Opakuji - v naproste vetsine pripadu to clovek nemusi az tak moc brat v uvahu, ale reakce na nazor "RAM je random access" musela zaznit, protoze to neni a uz asi nikdy nebude pravda.
Zle si vysvetlujes pojem RAM. A pravda to bude vzdy.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: tisnik 21. 09. 2016, 10:57:20
Opakuji - v naproste vetsine pripadu to clovek nemusi az tak moc brat v uvahu, ale reakce na nazor "RAM je random access" musela zaznit, protoze to neni a uz asi nikdy nebude pravda.
Zle si vysvetlujes pojem RAM. A pravda to bude vzdy.

V kontextu toho co resime (efektivita pristupu do pole primo nebo pres reference) to skutecne zadny random access neni. A brano do dusledku, na NUMA architekture muzes mit dokonce i locky pri pokusu o pristup do pameti.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: dustin 21. 09. 2016, 10:57:58
Zle si vysvetlujes pojem RAM. A pravda to bude vzdy.

Hm, tak by ji to asi chtělo přejmenovat.
Název: Re:Paměťová a výpočetní náročnost JVM vs .NET
Přispěvatel: PetrM 21. 09. 2016, 14:17:21
Opakuji - v naproste vetsine pripadu to clovek nemusi az tak moc brat v uvahu, ale reakce na nazor "RAM je random access" musela zaznit, protoze to neni a uz asi nikdy nebude pravda.
Zle si vysvetlujes pojem RAM. A pravda to bude vzdy.

RAM je zkratka, která nikdy nedávala smysl. Copak ROM, která má adresovatelný každý slovo, není taky RAM? Na smysl těch zkratek bych se moc nekoukal. Logičtější je ROM a RWM.

A systémová RAM opravdu náhodný přístup nemá ráda. A cokoliv "malýho" je pekelně drahý. Řekněme, že máme DDR s latencí 5-5-5 a chceme vyčíst v 64b systému 8B data. Burst je nastavený na osm slov:
OperaceTaktů
Vystavení RAS1
RAS-CAS Latence5
Vystavení CAS1
CAS-CS latence5
Čtení bloku (8 slov)4
Total16

Takže na vyčtení 8B z DDR SDRAM potřebuju 16 taktů sběrnice s tím, že se ve skutečnosti vyčte 64B dat, ale 56B se zahodí. Když do takové RAM leze člověk postupně s pomocí referencí, tak se může stát, že data načítá furt dokola a zahazuje další prvky, kdežto data v jednom bloku prolítnou sběrnici jak namydlený blesk... Blok 1024B se dá vycucat v 256 cyklech s plným adresováním (RAS i CAS). A když se to pak podrží v cache s přístupem 8B na jeden takt pro zpracování, je to prostě pohodička.