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.VPS nemusí být drahá ceny od 100Kč měsíčně. 1GB memory, 20GB data, 1 procesor
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.
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
pro .NET potřebujete WindowsNeni 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 ;)
Nepravda. Už jenom pro to, že pro .NET potřebujete Windows.
Pro obecný .NET nějaký takový existuje?
tipnu si ze nebude tak narocny na zdroje jako Javalebo neviete robit v jave zdielany hosting. nepustite si vedla seba 10 tomcatov ak bezna appka potrebuje 256 MB, nemate na to manazment.
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.
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?
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.
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.
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.
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í.
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?
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?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í.
Object[] poleObjektu = new Object[x];
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?
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];
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];
CitaceMyslí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?
K čemu by takový nesmysl byl?
Efektivnější využití procesorové cache?
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).
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.
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í.
Analogická věc v .NET Core zabere zhruba 4032 bajtů + velikost dalších dat ve třídě List.
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).
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).
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.
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).
class Salary {
double x;
}
class UserId {
int x;
}
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.
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.
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).
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).
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í.
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é.
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 poliTypická 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.
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 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.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.
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.Právě, že ne.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í.
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++.
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.
Typická webová aplikace je plná velkých matic intů.
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.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.Právě, že ne.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í.
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.
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.Právě, že ne.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í.
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.
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?
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.
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.).
Ale pokud ten seznam dává smyslAno, 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.Ale pokud ten seznam dává smyslAno, to je to klíčové. Porovnávat programovací jazyky podle jedné miliardtiny způsobu jejich využití je nesmysl.
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.
Docela bych rekl, ze je to dost umely priklad ne?
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.
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?
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.
CitaceRe: 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.
e[1000];
struct x
{
int id;
float perc;
};
int main()
{
struct x zaznam;
struct x pol
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.
Jasně. Takže libovolná implementace radix tree, spojového seznamu nebo HTML parseru bude efektivně využívat cache procesoru, pokud bude napsaná v C++.
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.
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.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.
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.
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.
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?
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.
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).
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.
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).
Jo tohle. Měl jsem za to, že je z kontextu jasné, co tím myslím. Moje chyba :(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.
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.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.
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.
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.
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.
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.
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.
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.
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.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.
Nebo je to úplně jinak a dozvím se to tady! :D
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
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.
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.
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.
tak prostě pořád není konkurence v něčem jiném
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.
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í).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ů.
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ů.Zasa jeden co si mysli, ze to zoptimalizuje lepsie ako SQL server.
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)).
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ů.Zasa jeden co si mysli, ze to zoptimalizuje lepsie ako SQL server.
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)).
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#?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.
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++.
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#.
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.
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.
tak nemusíte na SQL Server pokaždé posílat, kolikrát uživatel daný produkt vidělBý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.
tak nemusíte na SQL Server pokaždé posílat, kolikrát uživatel daný produkt vidělBý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).
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 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.
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?
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?
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?
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.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 msCo 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.
A těch méně než 10 ms bylo docíleno optimalizacemi zaměřenými na cache?
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.
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 dvojicTě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 generikEvidentně stále nechápete, že to není záležitost programovacího jazyka, ale toho, jak to programátor napíše.
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.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.
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.
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.Porovnat s čím? A co znamená „průchod pole“?
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 dvojicVzhledem 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 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ý
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).
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.
Kde je tam ta Java a moderní HW?
když .Net se nepoužívá a Java je nejrozšířenější.
Zkus si porovnat rychlost průchodu dlouhého pole.Porovnat s čím? A co znamená „průchod pole“?
#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;
}
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...).
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 :)
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.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.
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 :-)
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.
@@ -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;
}
length 1041522432.408077 time spent 0.760000
length 1041511428.008295 time spent 4.350000
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
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.
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.
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.
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));
}
zařaďte do testu i to, že ty struktury musíte do toho pole nejprve zkopírovat.
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“.
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.
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?
Cože???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???
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.
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í.
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.
Vytvoření pole referencí na objekty je javovinaA 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 :)Vytvoření pole referencí na objekty je javovinaA 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…
Vytvoření pole referencí na objekty je javovinaA 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…
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í.
Už mě to moc nebaví, takže jenom krátce.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.
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...
Už mě to moc nebaví, takže jenom krátce.že časť poľa hodnôt bude v jednej časti fyzickej pamäte a druhá časť nebude celkom inde.
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...
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.
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 ->
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.Už mě to moc nebaví, takže jenom krátce.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.
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...
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.
Už mě to moc nebaví, takže jenom krátce.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.
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...
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.
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í.
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.
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ě.
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.
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.
Zle si vysvetlujes pojem RAM. A pravda to bude vzdy.
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.
Operace | Taktů |
Vystavení RAS | 1 |
RAS-CAS Latence | 5 |
Vystavení CAS | 1 |
CAS-CS latence | 5 |
Čtení bloku (8 slov) | 4 |
Total | 16 |