Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »Richard Stallman přednáší ve středu 7. května od 16:30 na Technické univerzitě v Liberci o vlivu technologií na svobodu. Přednáška je určená jak odborné tak laické veřejnosti.
Java je hrozně pomalá a těžkopádná, zejména ta EE (cokoli enterprise je navíc fuj), proto píšeme v Pythonu nebo v Node.js – to ví přece každý zkušený internetový diskutér. Dále víme, že SQL a XML jsou pomalé a proto si do aplikací přidáváme NoSQL databáze jako memcached – no přece aby to bylo rychlejší, to dá rozum. Navíc se zbavíme otravných datových typů a středníků na koncích řádků a náš program bude mnohem přehlednější a bude se lépe udržovat. Tak si pojďme něco vyzkoušet…
Inspirací k tomuto pokusu byl Mirecův zápisek Non blocking IO vs kooperatívny multitasking na webe, takže pokud jste ho ještě nečetli, přečtěte si ho.
Webové aplikace psané v Javě EE se liší od těch psaných na platformách jako PHP mj. svým životním cyklem – javovskou aplikaci nasadíme (deploy) na server a tam potom dlouhodobě žije – může si tedy držet stav a to na několika úrovních:
(kromě toho tu máme další vychytávky jako EJBčka a jiné objekty, u kterých řídí vytváření a počet instancí kontejner, ale tím se teď zabývat nebudeme)
Díky tomu si informace o stavu můžeme držet na patřičné úrovni a nemusíme stav s každým HTTP požadavkem inicializovat a pak zase zahazovat. Díky tomu ani nepotřebujeme věci typu memcached – které jsou navíc pomalé, protože to znamená vyměňovat si data s jiným procesem, typicky pomocí TCP nebo UDP (byť v rámci localhostu) a provádět serializaci a deserializaci těchto dat. Místo toho pracujeme nativně s objekty našeho programovacího jazyka.
Navíc nemusíme řešit, zda se k memcached nepřipojí někdo cizí a nebude nám tam číst nebo dokonce zapisovat naše data. Smysl by to mělo jen tehdy, když bychom potřebovali sdílet data mezi více aplikacemi různých platforem – ale to není typický případ užití – většinou jde jen o workaround, který má vyřešit problém toho, že aplikace/platforma neumí sama držet stav a musí si ho někam externě uložit a pak zase načíst.
Napsal jsem javovský servlet se stejnou funkcionalitou – posílá klientovi citát dne:
package cz.frantovo.blog.servlet; import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author Ing. František Kučera (frantovo.cz) */ @WebServlet(name = "pokus", urlPatterns = {"/pokus/*"}) public class CitátDne extends HttpServlet { public static final String MSG_VAR = "msg_var"; private final Map<String, String> citát = new ConcurrentHashMap<>(); @Override public void init() throws ServletException { citát.put(MSG_VAR, "vyrok_2013-07-12"); citát.put("vyrok_2013-07-12", "vyrok pre dnesok"); } @Override protected void doGet(HttpServletRequest požadavek, HttpServletResponse odpověď) throws ServletException, IOException { String aktuálníKlíč = citát.get(MSG_VAR); String data = citát.get(aktuálníKlíč); odpověď.setContentType("text/plain"); odpověď.getOutputStream().println(data); } }a pustil na něm test:
ab -n 10000 -c 100 http://127.0.0.1:8080/pokus/
Concurrency Level: 100 Time taken for tests: 3.345 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 2700000 bytes HTML transferred: 180000 bytes Requests per second: 2989.80 [#/sec] (mean) Time per request: 33.447 [ms] (mean) Time per request: 0.334 [ms] (mean, across all concurrent requests) Transfer rate: 788.33 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 2 2.7 1 27 Processing: 5 31 11.0 30 100 Waiting: 2 30 10.8 29 100 Total: 12 33 10.2 32 100 Percentage of the requests served within a certain time (ms) 50% 32 66% 34 75% 36 80% 37 90% 43 95% 52 98% 71 99% 75 100% 100 (longest request)Zapomněl jsem do svého programu přidat nějaké kurvítko? Nebo mám o tolik rychlejší HW než Mirec?
Tiskni
Sdílej:
Jestli myslíš HW, tak to je virtuální server (KVM) s dvěma jádry a 2 GB RAM. Skutečný HW pod tím je Intel i7-920 Nehalem na 2.66 GHz z roku 2008.
Napiš
(myslím to vážně, rád bych to viděl, jak z hlediska výkonu, tak čitelnosti a délky programu)
Neviem, či haskell by bol vhodný pre priemerných javistov. V každom prípade typový systém haskellu je jedna z najkrajších vecí, ktorá ma v IT stretla (a to počítam aj sekretárku od vedľa).
Možná proto se protlačovala Java, protože je větší pravděpodobnost že ji zvládne i průměrný dělník - programátor.
A o tom to právě je – cílem je dodat kvalitní software (splňující požadavky zákazníka) a vejít se při tom do rozpočtu a termínů. Ne si hrát na nějaké elitářské programování pro geniální programátory.
Java trefila ten správný poměr mezi možnostmi jazyka a jednoduchostí, proto je tak úspěšná – ne že by ji násilím někdo někam tlačil.
Java trefila ten správný poměr mezi možnostmi jazyka a jednoduchostí, proto je tak úspěšná – ne že by ji násilím někdo někam tlačil.Vzpomínám si celkem dobře na to množství konferencí, přednášek a školení (většinou vstup i raut grátis, pro IT manžery firem byly zdarma i letenky), reklam i placených článků v časopisech jako CHIP, Byte a dalších forem propagace, které musely stát nemalé prostředky. To rozhodně nebylo o skromné nabídce, po které jim trh urval ruce.
Byly a jsou tu i bohatší firmy než Sun (IBM, HP, Dell, Microsoft, Google…), vlastní jazyk mohl protlačit kdokoli z nich, ale kdyby nebyl tak dobrý jako Java, tak by mu sebelepší reklama nepomohla. Microsoft se zase snaží tlačit svůj .NET a jeho jazyky a jemu v tom pomáhá ještě obrovský vendor-lock-in z minulosti a rozsáhlá síť zkorumpovaných (nebo vydíraných) „subdodavatelů“ a politiků – a přesto se ty důležité věci píší v Javě a ne .NETu.
Ještě k tomu lhaní – neříkal jsem, že Sun neinvestoval do reklamy, ale že Java je úspěšná díky svým vlastnostem, ne díky reklamě – kdyby ten správný poměr možností a jednoduchosti neměla, tak se ani s tou reklamou neujme.
U Haskellu je potřeba uvažovat nad implementací víc dopředu a komplexněI kdyz se mi Haskell celkem libi (jako matematicky konstrukt, ne jako jazyk na programovani), nejsem si jisty, ze je to az takova vyhoda. Jazyk je nastroj, takove GUI pro programatora. Cim vic se plete do cesty normalni praci, tim hur. Pokud musim vic uvazovat pri jeho pouzivani, zbyde mi mene cyklu na uvazovani nad resenou ulohou.
Pokud musim vic uvazovat pri jeho pouzivani, zbyde mi mene cyklu na uvazovani nad resenou ulohou.To je možný dojem, daný zřejmě neznalostí. Ve skutečnosti to naopak obvykle čas ušetří, když induktivní řešení může vést do slepé uličky a zpětně se kód opravuje a přepisuje. V haskellu ta deklarativnost a typový systém nutí napsat to rovnou správně, jen je nutné si to v hlavě nejdřív urovnat
Ve skutečnosti to naopak obvykle čas ušetří, když induktivní řešení může vést do slepé uličky a zpětně se kód opravuje a přepisuje.Mas na to nejakou studii, nebo je to jen zase dalsi pocit? Ja bych rekl, ze zrada je prave v tom "mozna". Mozna se dostanes do slepe ulicky, a mozna to bude pro danou aplikaci stacit. Software se prepisuje co chvili a predstava, ze neco napises napoprve spravne, zda se mi spise scestna, prestoze bych ji sam tak rad veril! (A mimochodem, co je vlastne spravne?) Elegance Haskellu se mi libi, ale nekdy je to holt pres ruku. Stejne tak, psat programy v dostatecne silnem typovem systemu v podstate znamena psat je dvakrat. Opravdu bychom je nemohli psat jen jednou? O jazyce, ktery ma (silne) typy jen uplne minimalne, chci o tom napsat svuj druhy blogpost, btw, ale zatim to nemam moc rozmyslene. Libi se mi pristup Paula Grahama - programovaci jazyk by mel poskytovat dostatecnou tvarnost na to, aby se v nem dalo experimentovat s prototypem, a teprve pozdeji ten vysledek "nechat ztuhnout" do konkretnejsi a efektivnejsi podoby. Hypoteticky jazyk, o kterem jsem psal ve svem prvnim blogpostu, se o tohle pokousi take. Nicmene, jak pisu niz, typovy system neni to, co mi na Haskellu vadi asi nejvic. Haskell beru jako urcity, velice zajimavy pokus. Ale jako smer.. asi uplne ne.
Opravdu bychom je nemohli psat jen jednou?
A který z těch dvou konců by měl být primární a který z něj odvozený? A co když budu potřebovat zorganizovat práci v týmu tak, že nejdřív se bude dělat ta odvozená část programu a pak teprve ta, ve které se měly definovat typy? A co programování stylem kdy jeden navrhne rozhraní (nebo napíše kostru třídy se signaturami metod) a další doplní ten zbytek?
To „psát dvakrát“ může vypadat hloupě, ale myslím, že někdy to může práci i šetřit. Navíc nemusí to být dvakrát to samé – na jednom konci můžou být konkrétnější typy a na druhém obecnější.
Rozumný kompromis podle mého je na rozhraních metod/funkcí deklarovat typy pořádně a uvnitř mít možnost typy odvozovat + k tomu mít slušné IDE, které mi hned ukáže typ. Tzn. mít možnost napsat uvnitř metody.
var proměnná1 = new Třída(); var proměnná2 = "ahoj";
nebo alespoň:
Map<Integer,String> mapa = new HashMap<>(); // místo new HashMap<Integer,String>();
A který z těch dvou konců by měl být primární a který z něj odvozený?Existuje ona Curry-Howard korespondence, o ktere tu tak pekne psal Radek Micek, takze na tehle urovni je to asi jako ptat se, kterou stranou si navlect tkanicku do bot. Z dostatecne silneho typoveho systemu lze chovani programu odvodit. Ze ho nemate, nu, to je jiny problem. Pak se to samozrejme nepise uplne dvakrat, moje tvrzeni odkazuje prave na tuto extremni situaci. (Stejne tak si myslim, ze automaticke testovani znamena napsat program dvakrat, ale to je na jinou diskusi.)
A co když budu potřebovat zorganizovat práci v týmu tak, že nejdřív se bude dělat ta odvozená část programu a pak teprve ta, ve které se měly definovat typy? A co programování stylem kdy jeden navrhne rozhraní (nebo napíše kostru třídy se signaturami metod) a další doplní ten zbytek?Oboji mi zni jako recept na prusvih. Ale proti gustu.. (A dikybohu delam ve firme, ktera to druhe nepraktikuje.) Jinak pro poradek - adhoc typy neznamenaji, ze typy nejsou. Jen se nezapisuji. Ale porad se na nich musite nejak dohodnout. Samozrejme, musite vedet, s jakymi daty pracujete. Jen tomu nedavate nazev, to je cele.
To „psát dvakrát“ může vypadat hloupě, ale myslím, že někdy to může práci i šetřit. Navíc nemusí to být dvakrát to samé – na jednom konci můžou být konkrétnější typy a na druhém obecnější.Na tohle uz jsem myslim reagoval. Rikam, chci o tom napsat blogpost, eventualne.
Jak chceš vytvářet velké věci, kdy jeden člověk nemá šanci stihnout udělat obě strany rozhranní?
O tom to je – odvozování je IMHO výhodné jen někdy.
V prvním případě ano – zatímco v posledním vůbec. Tam je potřeba mít předem dohodnutá rozhraní a poctivě deklarovat typy – i za cenu toho, že se budou psát 2× nebo 3×. Odvozovat se pak dá od toho rozhraní – v rámci dané komponenty nebo metody/funkce.
Jinak pro poradek - adhoc typy neznamenaji, ze typy nejsou. Jen se nezapisuji.
Vím, viz ten můj příklad var proměnná1 = …
– myslíš to takhle, ne? Proměnná má typ, i když jsem ho tam explicitně nezapsal.
Ale porad se na nich musite nejak dohodnout. Samozrejme, musite vedet, s jakymi daty pracujete. Jen tomu nedavate nazev, to je cele.
A ta dohoda typicky vypadá tak, že deklaruji, jaké typy očekávám na vstupu a jaké mohou ostatní očekávat na výstupu. Dá se samozřejmě říct: „na vstupu očekávám to, co leze z tamhleté části programu“ – jenže co když právě „tamhleta část“ ještě neexistuje, ještě ji nikdo nenapsal a já teď chci dělat na téhle části, která by z té neexistující měla být teoreticky odvozená?
Odvozování typů používám např. v SQL – když dělám funkci, která má pracovat s daty z určité tabulky, tak tam nepíšu např. INTEGER
ale tabulka.sloupeček%TYPE
. Jenže tady mám jistotu, že vždycky budu mít nejdřív tabulky a pak teprve budu dělat funkce – je jasné, co se má z čeho odvozovat.
Dovedu si ale představit situaci, že tabulky ještě nemám hotové nebo nemám úplně jasno o datových typech (vím, že to bude číslo, ale nevím např. jaké) nebo se např. můžou ještě přejmenovat tabulky a sloupečky… a budu chtít někomu zadat práci „napiš funkci, která počítá to a to“ – aby na tom mohl dělat už teď a nemusel čekat, až budou hotové tabulky. Tak mu buď pošlu kostru té tabulky (kde bude třeba jen ten jeden sloupeček, který ho zajímá), aby z ní mohl odvodit ten typ, nebo mu zadám dostatečně obecné1 typy, aby to nakonec na výslednou tabulku pasovalo. A můžeme dospět i k tomu, že ta jeho funkce nebude použitelná jen s tou mojí tabulkou, ale bude univerzálnější, znovupoužitelnější. A to je přesně ten případ, kdy na jednom konci máme konkrétnější typy a na druhém obecnější – nejsou od sebe odvozené.
P.S. Šikovné by mi přišlo něco jako „typedef“ – vlastní pojmenování typů, které odráží sémantiku, a pak vůbec nepoužívat primitivní datové typy, ale jen ty vlastní pojmenované – a kompilátor by pak kontroloval, jestli sedí i ta sémantika (ne jen ten skutečný typ pod tím).
[1] což je jednoduché u vstupů funkce – u výstupu je to horší
Vím, viz ten můj příklad var proměnná1 = …
– myslíš to takhle, ne? Proměnná má typ, i když jsem ho tam explicitně nezapsal.
Nejsem si ted uplne jisty - zalezi od semantiky. Charakteristickym rysem dynamickeho typovani je fakt, ze hodnoty maji typy, ale nikoli promenne. Takze pokud to var znamena jen "odvod zde typovou signaturu, jsem liny se s tim psat", pak je to neco jineho, nez dynamicke typovani (a neco jineho nez mam na mysli ja, coz je v podstate dynamicke typovani dovedene jeste trochu dal).
Šikovné by mi přišlo něco jako „typedef“ – vlastní pojmenování typů, které odráží sémantiku, a pak vůbec nepoužívat primitivní datové typy, ale jen ty vlastní pojmenované – a kompilátor by pak kontroloval, jestli sedí i ta sémantika (ne jen ten skutečný typ pod tím).To je sice teoreticky hezke, ale neresi to ten zakladni problem. Ten spociva v tom, ze cim explicitnejsi typy jsou, tim vic kontrol dostanes, ale na druhou stranu to znamena mensi flexibilitu (a vetsi sance, ze se to bude muset predelavat). Muj jazyk se snazi oddelit obe veci (flexibilitu jako default, kontroly do anotaci) a tim vyresit toto dilema. Tohle vsechno podrobneji rozeberu ve svem blogpostu - stay tuned.
Největším přínosem deklarování proměnných je detekce překlepů a možnost definování jejich viditelnosti (scope).
Souhlas. Ale na to by mohl stačit ten var proměnná = …
, kde se ten typ odvodí z hodnoty. Ale přiznám se, že i v rámci těla metody deklaruji někdy jiný (obecnější) typ, než jaký má hodnota.
Jinak i Haskell ma sva proti..Jistě, ale kromě nároků na IQ programátora a vyzrálost některých knihoven jich moc neshledávám, ale třeba mám jen malou představivost
Ale problem vidim prave v tech monadach. Prijde mi, ze rozbijeji modularitu.Někteří jdou ještě dál: http://gbracha.blogspot.cz/2011/06/types-are-anti-modular.html
Haskell, stejně jako jakýkoli jiný funkcionální jazyk, nemá šanci se v této době masově prosadit.Například Javascript. Kdyby i Haskell měl kudrnaté závorky, tak už se dávno prosadil.
Dávat JS jako příklad funkcionálního jazyka a dokonce srovnávat s haskellem je nesmysl.Ale to prece nedelam. Ja mluvil zcela jasne o tom, ze je to protipriklad teorii o rozsireni jazyka v dusledku propagandy. O tom jestli je funkcionalni nebyla vubec rec.
A že je javascript zvládnutelnější pro cvičenou opici než funkcionální jazyky by jen potvrdilo tezi p. Ponkráce a že to mělo vliv na jeho popularitu.
Škoda že třeba za Haskellem nestála komerční síla jakou byl Sun, který javu do korporátní sféry tvrdě protlačil.Simon Peyton-Jones adding the IO Monad to Haskell - ne, že bych něco proti Haskellu měl, chraň bůh, ale drtivá většina programů je o IO, takže ani Sun blahé paměti, by si na Haskellu vylámal zuby.
Btw. haskell se stále učím, živí mě ruby/rails/python/django/numpy/C. Jen vidím ten obrovský potenciál, který v sobě jak jazyk (Haskell98, Haskell2010), tak špičková implementace GHC skrývá. Bez ohledu na rozšířenost a bandwagon-bias.
Jen vidím ten obrovský potenciál, který v sobě jak jazyk (Haskell98, Haskell2010), tak špičková implementace GHC skrývá.Potencial tam jiste je, ale ma jeden velky hacek, a to je ten, ze staticka analyza ma svoje limity. Napr. nepocita s tim, na jaka data aplikaci realne pustite. Pozadavky se muzou menit s zivotem aplikace.. bude nekdo ochoten prepisovat typove signatury? Proto staticke typove systemy - podle meho nazoru - nejsou a nebudou konecne slovo. Leda ze bys vsechno stavel na typovych tridach, ale i to ma sva proti. Jinak taky pises o paralelnich aplikacich. Prijde mi, ze realne aplikace se paralelizuji jen dost obtizne, a ty casti, kde to jde dobre, se vetsinou schovavaji do knihoven, u kterych uz si nekdo tu praci dal. Takze je otazka, jestli jsou "lepsi paralelni primitivy" skutecne az takove lakadlo.
Když už někdo vkládá odkaz nebo citaci, tak bych očekával nějaký důkaz podporující tvrzení. Ale asi jsem příliš naivní.Vložil jsem odkaz na svůj mnoho let starý blogpost, kde ten důkaz je. A netvrdil jsem nic o reálných aplikacích ani javových frameworcích.
Z nedávna stejná zkušenost. Napsal jsem si CRC, parametrické. Nejdříve v D, kde jsem použil šablony a věci typu "static if", kde to šlo. Výsledek při 5000000 update() volání nad 256B polem jsem dopadl nejdříve 11s. Kód je tu. Nad tím jsem provedl stupidní úpravy typu, že před cyklem uložím členskou proměnnou do lokální a po cyklu zpět. D je tak hloupé, že to vůbec nezoptimalizuje a pokaždé šahá do paměti tam a zpět. Po té úpravě jsem se dostal na 6s. Pak sem posun a xor rozdělil na dva řádky, abych mu poradil, jak nějak by to šlo zoptimalizovat, protože generoval prasárnu. Bum a mám 5s. Pak jsem místo DMD zkusil LDC a mám 4.2s. ("dmd -O -release" a "ldc2 -O2", dmd nemá -O2)
Pak jsem to splácal do C++, opět parametry je známo během kompilace, takže kód by měl vylézt hezký... GCC s O2 a unroll loop 4.8s, clang - stejné parametry - 4.2s. Tady je vidět, že LDC i CLANG generují více méně stejně díky llvm.
Další pokusy v C# a javě. V obou je skoro stejný parametrický kód, oproti D a C jsou tam virtuální fce, pro "šablony" nelze používat číselné parametry, takže jsou známy až za běhu. JIT v javě docela hezky zoptimalizoval, dostávám se 3.8-4s, jak kdy. Za to mono je docela katastrofa, nejprve s 12s, po stejném hacku jako v D jsem se dostal na 7.2s, mono moc dobře neoptimalizuje.
C nemusí být vždycky výhra, Java může být rychlejší.A já si vždycky myslel, že Java nemůže být rychlejší než C, když je v C. Tím samozřejmě nemám namysli, že by jednotlivý program rychlejší být nemohl, když se v C udělá dostatečně pomalý.
nadměrná "optimalizace" může ve skutečnosti rychlosti snížit)Vidím, že si hraješ s pojmy jak s legem, ta nadměrná optimalizace se mi moc líbí.
kdežto u Javy se kompiluje z bytecode do strojového kódu dynamicky až na konkrétním stroji a lze tedy optimalizovat dynamicky, v závislosti na daném stroji.Tenhle argument se docela hojně používal pro buildování na konkrétní stroj na Gentoo. Změny v rychlosti se ovšem obvykle neukazovaly jako závratné, až na nějaké speciální úlohy. To je ovšem spíše dané tím, co se na ty počítače distribuuje, zda zdrojový kód, bajtkód nebo architekturně závislý kód.
Ono nejde jen o konkrétní stroj/CPU, ale o to, že JIT má k dispozici data, která proudí skrze program (množství, četnosti…). Někdy proto můžeš pozorovat zrychlení po určité době běhu programu.
C nemusí být vždycky výhra, Java může být rychlejší.Lze vycházet z toho, že obvyklé užití C je kompilace do statického programu. Naproti tomu asi nebudeš chtít postavit to, že při obvyklém užití je Java oproti C nehorázně pomalá. Tedy přijdeš s nápadem, že při velmi speciálním užití a za patřičné opatrnosti by teoreticky mohlo dojít k tomu, že bude javovský program díky JITu rychlejší než odpovídající program v C. A teď pokud se budeš pohybovat na čistě teoretické rovině, tak stejně musí přijít ten argument, že k JIT ve skutečnosti Javu nepotřebuješ. No a pokud se vrátíš na zem a budeš chtít argumentovat běžnou praxí namísto teoretických konstrukcí, tak bys musel přijít s nějakou třídou běžně řešených úloh, kde se overhead Javy neprojeví a naopak ho přebije JIT. A na to bych byl docela dost zvědavý.
Vidím, že si hraješ s pojmy jak s legem, ta nadměrná optimalizace se mi moc líbí.Tady jsem to zjednodušil, ale v tom blogpostu to popisuji přesně - tedy ve smyslu zapnutí optimalizací v GCC (nejhorší výsledky byly pro -O3).
Stejně jako C nemůže nikdy rychlostně vyhrát nad dobrým programátorem v assembleru, ne?
ioctl()
read()
a write()
se lze snadno vzdálit zavoláním fdopen()
po inicializaci socketu.
A jeje tak niekto je tu expert na výkon. Tak teda OK, v tomto prípade sa vôbec nekontaktuje memcached čo bolo vlastne nosnou časťou môjho blogu. Takže keď už sme teda pri porovnávaní penisu ... môj stroj je staručký thinkpad R61i s core2duo.
processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 15 model name : Intel(R) Core(TM)2 Duo CPU T5250 @ 1.50GHz stepping : 13 microcode : 0xa3 cpu MHz : 1000.000 cache size : 2048 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm dtherm bogomips : 2993.06 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management:
Takže som podľa vzoru javy vyhodil memcached a pekne krásne si čítam lokálnu premennú aby to bolo spravodlivé a po vzore javy som zapol jit kompilátor čím som dosiahol 5-20 násobný výkon (podľa druhu úlohy).
Requests per second: 3976.82 [#/sec] (mean) Time per request: 25.146 [ms] (mean) Time per request: 0.251 [ms] (mean, across all concurrent requests) Transfer rate: 454.38 [Kbytes/sec] received
A ešte zodpovedajúci python kód:
from eventlet import wsgi import eventlet MSG_VAR = "msg_var" citat = {MSG_VAR: "vyrok_2013-07-12", "vyrok_2013-07-12": "vyrok pre dnesok"} def application(environ, start_response): start_response("200 OK", [('Content-Type', 'text/plain')]) yield citat[citat[MSG_VAR]] wsgi.server(eventlet.listen(('127.0.0.1', 8888)), application, debug=False)
Pointa byla v tom, že memcached se často používá jako nouzové řešení v případech, kdy aplikace nedokáže držet stavové informace – typicky v PHP. Z principu je to ale neefektivní řešení protože data je potřeba serializovat/deserializovat a předávat si je s jiným procesem přes TCP soket.
Když už chci držet data v RAM, tak je můžu mít v tom samém procesu a jako objekty daného programovacího jazyka, včetně pohodlí datových typů. Držet je v jiném procesu a přistupovat k nim přes síť dává smysl, když s tím chci pracovat z víc aplikací současně (což ale není typické – většinou jde o cache pro jednu aplikaci).
Konkrétní čísla se těžko porovnávají, v tvém programu zase nevidím žádné směrování podle URL1 na jednotlivé „servlety“2 a další věci.
[1] asi to posílá na libovolný požadavek pořád tu samou odpověď – v té Javě je to řešené přes anotace (@WebServlet(urlPatterns = {"/pokus/*"})
) nebo web.xml
[2] nevím, jak se tomu říká v Pythonu
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): MSG_VAR = "msg_var" citat = {MSG_VAR: "vyrok_2013-07-12", "vyrok_2013-07-12": "vyrok pre dnesok"} def get(self): self.write(self.citat[self.citat[self.MSG_VAR]]) application = tornado.web.Application([ (r"/", MainHandler), ]) application.listen(8888) tornado.ioloop.IOLoop.instance().start()
Server Software: TornadoServer/3.1.1 Server Hostname: 127.0.0.1 Server Port: 8888 Document Path: / Document Length: 16 bytes Concurrency Level: 100 Time taken for tests: 2.519 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 2110000 bytes HTML transferred: 160000 bytes Requests per second: 3969.88 [#/sec] (mean) Time per request: 25.190 [ms] (mean) Time per request: 0.252 [ms] (mean, across all concurrent requests) Transfer rate: 818.01 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 1.3 1 19 Processing: 5 24 14.2 19 111 Waiting: 4 24 14.2 19 111 Total: 17 25 14.0 20 111 Percentage of the requests served within a certain time (ms) 50% 20 66% 21 75% 22 80% 23 90% 41 95% 49 98% 77 99% 104 100% 111 (longest request)
Tu je to aj s korektným url routingom.
A ešte aby som bol sviňa tak na core i5 v práci (povolený jediný worker, takže pracuje fakt s jediným jadrom) ...
Concurrency Level: 100 Time taken for tests: 0.562 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 2110000 bytes HTML transferred: 160000 bytes Requests per second: 17778.13 [#/sec] (mean) Time per request: 5.625 [ms] (mean) Time per request: 0.056 [ms] (mean, across all concurrent requests) Transfer rate: 3663.27 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 2 Processing: 1 6 3.3 5 24 Waiting: 1 6 3.3 5 24 Total: 3 6 3.3 5 24 Percentage of the requests served within a certain time (ms) 50% 5 66% 5 75% 5 80% 5 90% 6 95% 8 98% 20 99% 24 100% 24 (longest request)
Áno skutočne je python výrazne rýchlejší pretože sa interpretuje (ak keď v podstate s jitom sa to už interpretáciou nedá nazvať) jeden riadok kódu. Zvyšok je surovo vykonávaný c-čkovými knižnicami. Python je skutočne dobrý v zliepaní kusov vysoko optimalizovaného kódu a je teda vhodný aj na veľmi výkonnostne háklivé weby. Rozdiel vo výkone oproti jave je prakticky zanedbateľný lebo väčinu času sa čaká na databázu a sockety (tam je to riešené natívnymi knižnicami). Renderovanie šablón sa tiež rieši natívnymi knižnicami v C/C++, takže tam tiež nie je žiaden výrazný rozdiel oproti jave.
Zvyšok je surovo vykonávaný c-čkovými knižnicami. … Rozdiel vo výkone oproti jave je prakticky zanedbateľný lebo väčinu času sa čaká na databázu a sockety (tam je to riešené natívnymi knižnicami). Renderovanie šablón sa tiež rieši natívnymi knižnicami v C/C++, takže tam tiež nie je žiaden výrazný rozdiel oproti jave.
Takže tam zase bude velký rozdíl v přenositelnosti…
Když už chci držet data v RAM, tak je můžu mít v tom samém procesu a jako objekty daného programovacího jazyka, včetně pohodlí datových typů. Držet je v jiném procesu a přistupovat k nim přes síť dává smysl, když s tím chci pracovat z víc aplikací současně (což ale není typické – většinou jde o cache pro jednu aplikaci).Nebo když mám aplikaci pod takovou zátěží, že jeden fyzický stroj na to už nestačí, nebo by jeho cena na jednotku výpočetního výkonu byla výrazně vyšší než cluster z více kusů "běžného" HW.
Ani když někdo programuje v Pythonu stylem, jako by to bylo PHP? (uskladňuje si objekty v nějakém externím procesu, ke kterému se připojuje po síti, místo aby si je jednoduše uložil do proměnné ve svém jazyce a přistupoval k nim – patřičně synchronizovaně – z více vláken)
Ešte zopár komentárov k zvyšným záležitostiam v blogu:
Java je hrozně pomalá a těžkopádná, zejména ta EE (cokoli enterprise je navíc fuj), proto píšeme v Pythonu nebo v Node.js
Neviem ako ostatní, ja píšem v interpretovaných jazykoch pretože mi stačí napísať 1/4 kódu čo v Jave. Som lenivý a hardvér je lacný.
Dále víme, že SQL a XML jsou pomalé a proto si do aplikací přidáváme NoSQL
Ta diky, ja som jedným z najväčších odporcov NoSQL, možno to z mojich blogov nevyplýva pretože nenadávam na všetko, čo nepoužívam. Nech mi nikto nekecá, že join nepotrebujem, fakt si radšej poriadne navrhnem db a hodím všetko do postgresql a v prípade špecialít použijem hstore.
databáze jako memcached
Mmecached je generický key/data storage server. Používam ho na ukladanie rôznych predžúvaných dát, session ... Umožňuje mi to pohodlne pristupovať k týmto dátam z iných procesov (napr jabber server).
Webové aplikace psané v Javě EE se liší od těch psaných na platformách jako PHP mj. svým životním cyklem – javovskou aplikaci nasadíme (deploy) na server a tam potom dlouhodobě žije – může si tedy držet stav a to na několika úrovních
Líši sa tým v niečom oproti bežným python / node webovým aplikáciám? Python sa zvyčajne nepoužíval ako cgi skript a node už vôbec nie. Nič sa nenačítava znovu pri requeste, dáta sa dajú medzi requestmi sharovať, ale nie je to považované za dobrý zvyk (minimálne to zabije flexibilitu prístupu z iných procesov).
Na záver môj blog vôbec nebol o performance, ale spôsobu zápisu I/O, elegancii, správe kódu. Benchmark bol použitý len na demonštráciu, že oba prípady (gevent aj nodejs) dokážu bez zablokovania spracovať veľké množstvo požiadaviek aj napriek úplne rozdielnemu spôsobu zápisu programu.
Som lenivý a hardvér je lacný.Vidím to podobně – a právě proto píšu většinu v té Javě.
Neviem ako ostatní, ja píšem v interpretovaných jazykoch pretože mi stačí napísať 1/4 kódu čo v Jave.Jak by v Pythonu vypadal následující kus aplikace?
package cz.frantovo.blog.servlet.správa; import cz.frantovo.blog.Soubory; import cz.frantovo.blog.entity.Soubor; import java.math.BigInteger; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.mail.MessagingException; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; /** * * @author Ing. František Kučera (frantovo.cz) */ @Path("autor/soubory") @Stateless public class SouboryAPI { @EJB Soubory ejb; @POST @Path("/") @Consumes("application/octet-stream") @Produces("text/plain") public String uložSoubor( byte[] data, @HeaderParam("X-Clanek") Integer článek, @HeaderParam("X-Nazev") String názevSouboru, @HeaderParam("X-Popis") String popisSouboru, @HeaderParam("X-Vypis") boolean výpis) { Soubor soubor = new Soubor(); soubor.setNázev(názevSouboru); soubor.setPopis(popisSouboru); soubor.setVýpis(výpis); soubor.setČlánek(článek); soubor = ejb.uložSoubor(soubor, data); return "Soubor byl uložen pod číslem: " + soubor.getId() + "\n"; } @GET @Path("{článek}") @Produces("text/plain") public String vypišSouboryČlánku(@PathParam("článek") BigInteger článek) { return "Na GET požadavky odpovíme nějak jinak…"; } }
@Path("autor/soubory")
deklaruji, URL cestu, na které bude tenhle kus aplikace naslouchat@PathParam("článek")
), HTTP hlavičky (@HeaderParam("X-Nazev")
) nebo parametry (@QueryParam("…")
, @FormParam("…")
…) se mapují na argumenty metody a převádějí na konkrétní datové typy (pokud se někdo pokusí např. místo čísla podstrčit text, tak dojde k chybě a ani se to k tomu mému kódu nedostane)Jde tam psát podobně deklarativně, nebo budu potřebovat hromadu IFů, porovnávání textových řetězců nebo regulárních výrazů a přetypování nebo ručních kontrol?
Nech mi nikto nekecá, že join nepotrebujem, fakt si radšej poriadne navrhnem db a hodím všetko do postgresql
Tak v tomhle se shodneme
dáta sa dajú medzi requestmi sharovať, ale nie je to považované za dobrý zvyk (minimálne to zabije flexibilitu prístupu z iných procesov).Proč bych měl k interním datům aplikace přistupovat z jiných procesů? Chápu ten případ použití memcached, jak jsi psal, že k tomu přistupuješ z webu i z jabber serveru – to je dobrý příklad. Ale jinak to opravdu smysl nedává.
Na záver môj blog vôbec nebol o performance, ale spôsobu zápisu I/O, elegancii, správe kódu.
To považuji za důležité – a právě proto se mi nelíbí, když se vedle sebe míchají věci typu na jaké IP a portu naslouchat a samotná byznys logika aplikace.
Jak by v Pythonu vypadal následující kus aplikace?
Záleží od frameworku ale v zásade rovnako.
Proč bych měl k interním datům aplikace přistupovat z jiných procesů? Chápu ten případ použití memcached, jak jsi psal, že k tomu přistupuješ z webu i z jabber serveru – to je dobrý příklad. Ale jinak to opravdu smysl nedává.
To bol príklad ktorým som demonštroval ako blokovanie I/O funguje, kedy je užitočné a kedy je škodlivé. Kľudne som mohol hrabnúť na SQL databázu, ale ruku na srdce komu by sa chcelo v node.js hrabať do postgresql? Mne nie, takže som použil niečo iné, čo aj tak musí bežať cez tcp/ip - memcached. Inak ho používal len na session (kvôli autentifikácii iných služieb) a predžúvané šablóny.
Proč bych měl k interním datům aplikace přistupovat z jiných procesů?
Príkladov je veľa, minimálne session by som tam dával a to z rôznych dôvodov. Uvádzal som autorizáciu z iných služieb (robil som jabber, ale môže byť prakticky čokoľvek). Zaujímavým použitím je napr. pri deployi spustiť nový aplikačný server a nechať priamo webserver podľa session routovať všetky práve existujúce sessiony na starú inštanciu. Po vypršaní session užívateľa, alebo odhlásení automaticky prejde na novšiu verziu webovej aplikácie. Ďalej je tu samozrejme distribuovanosť, možnosť aplikačný server v noci keď prebieha záloha úplne vypnúť čím sa ušetrí RAM (python aplikačný server dokáže v prípade požiadavky nabehnúť do sekundy, takže vypínanie po pár minútach nečinnosti nie je v zásade žiaden problém a na zdieľanom serveri je to fakt na nezaplatenie). Nad aplikačným serverom stojí správca procesov, ktorý spúšťa skutočné separátne procesy. V managovaných jazykoch nevyzerá ako veľká výhoda, ale aj java má jni a občas sú knižnice na špecializované veci (opencv) len natívne a môžu v nich zniknúť chyby čo buď spôsobí leak, alebo kľudne aj niečo horšie. Ja si v takom prípade môžem bez problémov pri prekročení RAM, alebo procesorového času nechať aplikačný server zabiť a o žiadne dáta neprídem.
Viz tenhle starší článek. Záleží na projektu, někdy píšu česky, někdy anglicky, zrovna tahle aplikace slouží jen pro mě a ani jsem to neplánoval dávat nikomu číst – akorát se to zrovna hodilo jako příklad k tomuto tématu.
BTW: diakritika a různé další unicode znaky jsou v Javě legální identifikátory – někdy je dobré otestovat, že všechno funguje tak dobře, jak je to popsané ve specifikaci Mj. jsem tím otestoval, že v Pygmentize1 je chyba – nepočítá s jinými znaky než ASCII, i když tam (v Javě a jinde) být můžou. Pro XML to už opravili, pro Javu tam myslím mají chybu i v poslední verzi.
[1] zvýrazňovač syntaxe, není součást Javy, je psaný v Pythonu
někdy píšu českyVe skutecnosti pises nejakym hybridem, napr.
soubor.setPopis(...)
Viz specifikace JavaBeans. Když si ty metody pojmenuješ třeba dejNěco()
nebo nastavNěco()
, tak je to sice zkompilovatelný zdroják, ale není to JavaBean a nemůžeš instance takové třídy použít tam, kde se JavaBean vyžaduje – např. v JSP (tam totiž přistupuješ k vlastnostem instance jako k instance.něco
bez nějakých get
a set
).
Python sa zapisuje v rot13. Je to v špecifikácii. To že je tam nejaká kravina neznamená, že to hneď musím používať.
# -*- coding: rot13 -*- cevag h"Uryyb nopyvahkh!"
Ta čeština ve zdrojácích je ale otázka znakové sady (resp. povolené podmnožiny z ní) nikoli kódování znaků (i v Javě můžeš psát v různých kódováních a rot13 by tam šlo udělat taky).
Toto je zdroják kódovaný v rot13. Alebo si niekto myslí, že cevag je príkaz jazyka? Python umožňuje písať zdrojový kód v ľubovoľnom kódovaní, default ascii, ale kódovanie nie je pevne zadrátované.
V jedné konkrétní session je ti to ale na nic, pokud k těm samým datům1 chceš přistupovat ze všech relací a všech HTTP požadavků.
[1] resp. objektům, které spojují data a chování, ne jen k nějakým neživým serializovaným strukturám
Ano, zkoušel jsem i Collections.synchronizedMap()
a výsledky byly horší. Ale proč to zpomalovat synchronizací na místě, kde být nemusí?
Ale proč to zpomalovat synchronizací na místě, kde být nemusí?nemyslel jsem to tak, ze by se to melo nekde zamerne zpomalovat, jen ze by se melo srovnavat srovnatelne. Pokud node.js a vsechno pod nim pri cteni nic nesynchronizuje, nezamyka atd.(*), pak ok, ale pokud ne, tak se porovnaji hrusky s jabkama (framework, ktery nekde uvnitr synchronizuje s kodem, ktery nikde nic nesynchronizuje)
Sockety musia byť samozrejme synchronizované, memcache protokol striktne vyžaduje poradie dotaz - odpoveď (nie je možné prerušiť medzi dotazom a odpoveďou a vykonať ďalší dotaz, musia byť skutočne vykonané sekvenčne).
[...] a svoje algoritmy taky, a že už jsem jich vymyslel hodně..Podělíš se s námi o pár kousků?
Hehe jo... já si to většinou nejdřív napíšu na papír a dumám nad tím ze všech směrů aby to náhodou nedopadlo tak... jako když postavíš barák ale zapomeneš na dveře :D:D... Je mi jasné, že tyhle techniky ovládá každý programátor,.. já s programováním začínám už léta není na to tolik času, nemám to jako práci, takže si osvojuji pár technik které potřebuji, abych si mohl dělat větší projektíky :)
Btw, offtopic, nevíš co se dnes používá pro vektorové paralelní výpočty ? Cray nebo Nec pochybuju že seženu, takže POWER 7 nebo MIPS bys doporučil ?
Není to zrovna autoritativní zdroj, ale např. na Wikipedii to tam řadí a odkazují u toho nějaký článek.
NoSQL je to určitě, otázka je, jestli je to i databáze – záleží jak ji definuješ a jaké budeš mít minimální nároky na SW, aby se mu dalo říkat databáze. IMHO se to tam klidně řadit může – ostatně taková PostgreSQL nebo MySQL ve které si vytvoříš tabulku, která je jen v paměti, tak je taky pořád databáze.
K tomu si požičiam jeden príspevok z môjho blogu:
> [1, 2, 3, 10].sort() [1, 10, 2, 3]
Toľko logických vecí v iných jazykoch nenájdete ;)