Vlákno názorů k článku Nechte Go plavat, teď sviští Java od Petr M - No, mám tady na stole jednu desku. Procesor...

  • Článek je starý, nové názory již nelze přidávat.
  • 4. 12. 2018 8:32

    Petr M (neregistrovaný)

    No, mám tady na stole jednu desku. Procesor honím na 168MHz (vychází tak nejlíp časování periferek, dal by o něco víc). Má to 4x64 kiB RAM + 2x 1MB FLAH.

    Mám tam ovladače pro Ethernet dělat v Javě? VM tam nedostanu ani omylem, nevím co Java přibalí z knihoven a jestli toho nebude v té binárce 0,5GB - pokud jo, nic s tím neudělám. Zaintegrovat HW pro HASH a HW crypto engine by byla ještě o level větší sranda... A nesmí to kleknout kvůli fragmentaci paměti.

  • 4. 12. 2018 10:21

    Petr M (neregistrovaný)

    Článek je o tom, že je Java použitelná i na low level věci. Tak se ptám, jestli by Java dala i takovouhle věc.
    Ono totiž
    - C blbě pracuje s objektama (socket atd. se jako třída přímo nabízí, takže to smrdí OOP)
    - C++ má náročnou správu paměti
    - Go - zatím jsem nezkoumal možnosti
    - Java - viz komentáž výše. Nevím, co všechno se tam pokusí narvat

    Napadá někoho jiný řešení?

  • 4. 12. 2018 12:54

    MarSik (neregistrovaný)

    > - C++ má náročnou správu paměti

    I C++11 s make_ptr? Protože evoluce smart pointerů se podle mě docela povedla.

  • 4. 12. 2018 13:09

    KarelI

    C++ má samo o sobě správu paměti problematickou jak z hlediska programátora tak runtime a C++11 pointery jsou jen slabá záplata na tyto problémy. Ve skutečnosti to horko těžko řeší existující a přitom přináší nové komplikace.

  • 4. 12. 2018 13:30

    MarSik (neregistrovaný)

    Uh, prosím? Můžete být konkrétnější?

    C++ runtime? To je jako co? libc? To samé, co se používá prakticky pro všechny binárky v linuxu? Nebo myslíte standardní knihovnu a implementaci new v ní?

    Já znám spoustu nevýhod C++, ale ten komentář nedává smysl.

  • 4. 12. 2018 13:57

    KarelI

    Z hlediska programátora - musí se rozmyslet, kde objekt založí - heap nebo stack, kdo bude vlastníkem, kdy je případně třeba vlastnictví předat, nově do toho přichází unique/shared. To vše ovlivňuje jak se bude objekt předávat dál (hodnota, reference, pointer, ...), jak bude algoritmus navržen atd. U složitějších algoritmů to v podstatě vede na to, že programátor píše vlastní obdobu GC zas a znovu.
    Z hlediska runtime - je zde mnohem složitější logika jak při alokaci tak dealokaci, výkonnostní dopady v případě sdílených pointerů, nevyhnutelné problémy jako např. defragmentace. To následně dále vyvolává tlak na programátora, aby tomu ještě víc přizpůsoboval design programu, musel optimalizovat apod.

    Ve výsledku je programátor nucen zabývat se těmito aspekty v C++ násobně déle než kolik na to je potřeba třeba v javě (ale vlastně v čemkoli co má rozumný GC).

    Jedinou výhodu kterou za to dostaneme jsou nižší paměťové nároky a někdy se může hodit deterministická dealokace. Samozřejmě existují případy, kdy je lepší to psát v C++ (programátor je dostupnější než RAM), ale většinou jsou výše uvedená negativa příliš.

  • 4. 12. 2018 14:15

    unicode (neregistrovaný)

    V C/C++ se člověk může rozhodnout zda heap nebo stack, u GC jazyků může v ten stack jen doufat.

  • 4. 12. 2018 14:22

    KarelI

    > V C/C++ se člověk může rozhodnout

    Lépe řečeno se člověk rozhodovat _musí vždy_ a v drtivé většině případů je takové rozhodování naprosto zbytečné s tím, že bude přepisovat hlavičky hromady funkcí pokud se rozhodl blbě.

  • 4. 12. 2018 17:28

    echo zulu (neregistrovaný)

    No a nie je to skôr tak, že sa človek primárne rozhoduje o iných veciach, ako napríklad či chce mať prístup k danému prostriedku zdieľaný, alebo či je jeho vlastníctvo exkluzívne, alebo či potrebuje presne vedieť kedy skončí životnosť objektu, alebo podobné záležitosti a na základe toho potom vyplynie typ objektu, miesto jeho existencie a signatúra funkcie? Ja si myslím, že je :-) No a ak má chaos v tom ako to vlastne má byť, tak je jasné, že to bude prepisovať. Ale je to chyba C++? To ani náhodou.

    C++ dáva možnosti. Pokojne môžeš písať program s tým, že každá dátová štruktúra je dynamicky alokovaná a zdieľaná, fungovať to bude a nemusíš nič prepisovať. Je to efektívne? Nie. Ale efektivita nie je zadarmo, musíš o nej niečo vedieť a niečo pre ňu urobiť. Existuje programovací jazyk, ktorý dáva tieto možnosti automaticky a človek pre to nemusí nič urobiť? Ja neviem, rád sa niečo nové naučím, ale dosť o tom pochybujem.

    A potom, ktorý rozumný programátor by používal C++, keď nepotrebuje možnosti, ktoré C++ poskytuje?

  • 4. 12. 2018 19:40

    KarelI

    U naprosté většiny objektů nepotřebuju řešit, zda bude sdílen či ne, kdy skončí životnost apod. Dokonce je to tak, že díky tomu, že tyto věci není potřeba vyhodnotit, tak to vede na jednodušší algoritmus a kód.
    Dále, ať už je objekt takový či makový, nemá to vliv na hlavičku funkce, do které ho chci poslat. To samozřejmě výrazně usnadňuje vývoj, údržbu, předělávky atd.
    To že v C++ musím dělat tato rozhodnutí pro každou jednotlivou instanci a každý jednotlivý parametr je samozřejmě vlastnost C++ (nenazýval bych to až tak chybou), v jazycích jako java to pro většinu instancí není nutné.
    Další faktor je, že z mnoha důvodů je dobré mít konstantní objekty (abych nemusel řešit to sdílení apod.). To ovšem vede na vyšší nároky na alokátor, jenže založit objekt je v C++ výrazně dražší než třeba v JVM. To opět zvyšuje pravděpodobnost, že toho programátor v C++ bude muset řešit víc než je nutné jinde.

    > Pokojne môžeš písať program s tým, že každá dátová štruktúra je dynamicky alokovaná a zdieľaná, fungovať to bude a nemusíš nič prepisovať
    To samozřejmě fungovat nebude, stačí mít mezi objekty cyklus a už nemůžu použít shared_ptr. Pokud ho nepoužiju, musím řešit vlastnictví. A už se to veze...

    > efektivita nie je zadarmo, musíš o nej niečo vedieť a niečo pre ňu urobiť
    Anebo můžu použít platformu, která 95% těch situací vyřeší sama a já se zatím můžu zabývat tím co chci řešit já.

  • 5. 12. 2018 15:12

    echo zulu (neregistrovaný)

    > U naprosté většiny objektů nepotřebuju řešit, zda bude sdílen či ne, kdy skončí životnost apod.
    Keď niečo neriešiš osobne, tak to za teba vyrieši niekto iný a je otázka, či ti to tak vyhovuje. Mne nie.

    > Dále, ať už je objekt takový či makový, nemá to vliv na hlavičku funkce, do které ho chci poslat.
    To aký je objekt nie, to ani nikto netvrdí. Vlastníctvo a pod. neriešime kvôli samotnému objektu, ale kvôli tomu, ako s ním pracujeme. Vo funkciách. Riešime, či je objekt vo funkcii vytvorený a vrátený volajúcemu, alebo či z prijatého objektu vo funkcii iba čítame alebo ho aj modifikujeme alebo objekt kompletne nahradíme iným objektom, alebo či ten objekt vo funkcii končí svoju životnosť, v iných prípadoch je naopak rozumné zabezpečiť, aby objekt počas volania funkcie nezanikol, atď. (Nepochybujem, že toto vieš aj sám.) A podľa toho akú požadujeme funkčnosť volíme argumenty funkcií.

    > To že v C++ musím dělat tato rozhodnutí pro každou jednotlivou instanci a každý jednotlivý parametr
    Stále si myslím, že to naozaj nemusíš. Môžeš sa správať na základe štandardných odporúčaní, teda opakovať stále jedno počiatočné rozhodnutie pre daný kontext, a v odôvodnených prípadoch sa môžeš rozhodnúť pre niečo iné. Keď vieš, že za to získaš niečo, čo potrebuješ.

    > jenže založit objekt je v C++ výrazně dražší než třeba v JVM
    S JVM nepracujem, tak neviem ako to myslíš, ale keď chcem, aby som mal v C++ objekt vytvorený rýchlo, čo sa týka objektov, ktorých mám v aplikácii kvantum, tak si odhadnem koľko ich asi budem mať, predalokujem pamäť pre všetky naraz (zjednodušene povedané), vytvorím vlastný "alokátor" a vytvárané objekty budú existovať v rámci predalokovanej pamäťovej oblasti. Keď chcem, tak tú oblasť môžem mať inicializovanú blokom objektov načítaných z disku, alebo iba namapovanú zo súboru, na základie služieb OS. Takže vo finále vytvorenie jedného objektu je vlastne práca s ukazovateľom a s nejakou internou dátovou štruktúrou, v ktorej je evidencia voľných a obsadených blokov (zoznam, strom, bitová mapa, čokoľvek iné), prípadne ešte inicializácia jednotlivých členských premenných vytváraného objektu, pokiaľ ich naozaj vytváram a neboli načítané alebo namapované. Uvoľnenie jednotlivej položky je ešte jednoduchšie a uvoľnenie celého bloku ani nemusím písať. Fragmentácia nula. JVM má nejakú rýchlejšiu/lac­nejšiu metódu?

    > ... že toho programátor v C++ bude muset řešit víc než je nutné jinde.
    Naozaj zďaleka nie vždy a pokiaľ za to dostane niečo, čo inde nie, tak v tom nevidím problém.

    > To samozřejmě fungovat nebude, stačí mít mezi objekty cyklus
    Nechápem.. Myslíš cyklus ako for, while, atď? Tu neviem, čo napísať, už dávno používam štandardné algoritmy.

    Alebo myslíš dva objekty, ktoré na seba vzájomne držia ukazovateľ? O tom sa ale nebavíme, reagoval som na zmienku o argumentoch funkcií. A pokiaľ nechceš, aby sa inkrementoval počet, tak ten zdieľaný ukazovateľ odovzdáš odkazom.

    Alebo môžeš do funkcií posielať holý ukazovateľ. Aj tak nechceš riešiť vlastníctvo, tak je to jedno, nie? :)

    > Anebo můžu použít platformu, která 95% těch situací vyřeší sama
    To samozrejme môžeš, ale vtedy asi nespadáš pod definíciu poslednej vety môjho komentára, pretože tam spadá tých "5%" vecí, ktoré sa samé nevyriešia.

    Vo finále nechápem o čom sa bavíme, možno iba nepatríš medzi tých, ktorí vlastnosti C++ potrebujú. Ale to je úplne v poriadku.

  • 5. 12. 2018 15:43

    KarelI

    > Vo finále nechápem o čom sa bavíme

    Původně jsem vysvětloval MarSikovi tvrzení, že C++ má náročnou správu paměti. Tvůj příspěvek to dokresluje naprosto skvěle.

    Vytváření vlastních alokátorů je věc, kterou jsem viděl mockrát, dokonce jsou jedinci (i přítomni v této diskuzi), kteří se tím chlubí. Ukazuje to, jak je správa paměti v C++ špatná.

    > JVM má nejakú rýchlejšiu/lac­nejšiu metódu?
    Samozřejmě, posune pointer a vrátí původní hodnotu, je to zhruba na 2 instrukce.

    > Alebo myslíš dva objekty, ktoré na seba vzájomne držia ukazovateľ? O tom sa ale nebavíme,
    O tom se musíme bavit. V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat. A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí. Tvůj návrh prostě nelze korektně realizovat.

  • 5. 12. 2018 16:02

    oss (neregistrovaný)

    Ja suhlasim z predoslim prispevkom (od zulu). To, ze sa programator moze rozhodnut kam da objekt ci na haldu alebo heap je neskutocna vyhoda a nie len v perfomace.

    V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++ a to niekolko nasobne a nie je to len pusnutie pointera. (C# to riesi tym, ze vies pouzit struktury, ktore su na zasobniku, alebo direktivou stackalloc).

    >O tom se musíme bavit. V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat. A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí. Tvůj návrh prostě nelze korektně realizovat.

    To napriklad Qt riesi elegantne registraciou v "parent" objekte.

    Ono tie vycitky vysie na spravu objektov v C++ pramenia z jeho absolutnej neznalosti a neznalosti novych srandardov. V nich sa o spravu pameti clovek nemusi starat skoro vobec. Staci pochopit tu fylozofiu.

  • 5. 12. 2018 16:28

    KarelI

    > To, ze sa programator moze rozhodnut
    Znovu opakuji - ne že se může rozhodnout. On to rozhodnutí _musí_ dělat pokaždé u každé instance. To je poněkud rozdíl.

    > V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++
    Lze snadno vyvrátit benchmarkem. Mě vyšla průchodnost JVM asi desetinásobná oproti C++ v MSVC. Pokud si dobře pamatuju, C++ dokázalo alokovat nižší desítky milionů objektů za sekundu, JVM byla na stovkách.

    > To napriklad Qt riesi elegantne registraciou v "parent" objekte.
    A co když něco jako "parent" neexistuje? To tam pak musím uměle dodat? Pokud to jsou GUI komponenty, tak je to jasné, ale jsou datové struktury, kde jeden parent není.

    > z jeho absolutnej neznalosti a neznalosti novych srandardov. V nich sa o spravu pameti clovek nemusi starat skoro vobec. Staci pochopit tu fylozofiu.
    Jasně. A pak to změříš a zjistíš, že je to pomalé a necháš standardy standardama.

  • 5. 12. 2018 16:58

    kraxna (neregistrovaný)

    > V Jave (a inych GC jazykoch) je vetyvornie objektu stale drahsie ako jeho vytvorenie na halde v C++ a to niekolko nasobne a nie je to len pusnutie pointera. (C# to riesi tym, ze vies pouzit struktury, ktore su na zasobniku, alebo direktivou stackalloc).

    Citation needed. Zni to spis jako tvuj pocit, protoze to neni pravda :-)

    Napr. jeden microbenchmark (nutno dodat, velmi stary): https://blog.cfelde.com/2010/06/c-vs-java-performance/

    Samozrejme hodne zalezi na konkretnim use case, obecne jsou situace kdy C++ alokace je rychlejsi a kde alokace JVM je rychlejsi, ale to co tvrdis je pitomost, protoze nekolikanasobne pomalejsi alokace v Jave proste obecne neni vuci C++.

  • 5. 12. 2018 17:22

    echo zulu (neregistrovaný)

    > Původně jsem vysvětloval MarSikovi tvrzení, že C++ má náročnou správu paměti. Tvůj příspěvek to dokresluje naprosto skvěle.
    To je tvoj osobný názor, pravdepodobne na základe toho, že nepotrebuješ komplexnú funkčnosť a stačí ti obmedzená sada.

    > Samozřejmě, posune pointer a vrátí původní hodnotu, je to zhruba na 2 instrukce
    A dostaneš tým tú istú funkčnosť? Objekt alokovaný v rámci sady objektov v bloku alokovanom naraz a uvoľnenom naraz, držanej lokálne v jednej oblasti pamäti, prípadne úplne spojito a bez medzier (až na prípadné zarovnanie)? Alebo si myslíš, že to sú veci, za ktoré nie je nikto ochotný zaplatiť? A aj rýchlosť? A to všetko na 2 inštrukcie? Porovnávame naozaj porovnateľné?

    > O tom se musíme bavit.
    Nie. O tom by sme sa teoreticky mohli baviť, keby som reagoval na tento kontext. Ja som reagoval na hlavičky funkcií.

    > V C++ prostě nemůžeš automaticky vše udělat shared a doufat, že to bude fungovat
    Ja to tak samozrejme nerobím, nijako ma neobťažuje deklarovať veci podľa potreby. Paradoxne, rebase kvôli tomuto naozaj nerobievam. Ale ak to niekoho obťažuje, nevidím dôvod prečo by to v hlavičkách funkcií nefungovalo.

    A keď by sme sa teda mali baviť o dátových štruktúrach s cyklickými odkazmi, tak máme silné ukazovatele a slabé ukazovatele.

    > A nemůžeš vše jen tak předávat raw pointerem, protože pak nevíš, kdy to zmizí.
    Všimol si si, že o holých ukazovateľoch píšem v kontexte, že neriešiš životnosť? Písal si to v príspevku, na ktorý reagujem. Tak prečo ju riešiš teraz?

    Odhliadnuc od toho, zmizne "to" vtedy, keď to uvoľníš. Alebo keď ukazovateľ prepíšeš iným obsahom. Keď to neuvoľníš a keď ukazovateľ neprepíšeš, tak to nezmizne.

    Základný problém v správe pamäti ale nie je ani tak to, že niečo zmizne, keď nechceš, aby to zmizlo, ale to, že niečo nezmizne vtedy keď už nechceš, aby to existovalo, teda napríklad pri neošetrenej výnimke.

    Ale aj táto časť debaty je v podstate zbytočná, pretože vyššie som spomenul, že vo väčšine prípadov použiješ odporúčania, ktoré už nejaký čas sú v zmysle čo najviac objektov v zásobníku s ich automatickou deštrukciou, odovzdávanie odkazom, prípadne presunutie do volanej funkcie a používanie toho istého mechanizmu v rámci RAII.

  • 5. 12. 2018 18:19

    KarelI

    > To je tvoj osobný názor, pravdepodobne na základe toho, že nepotrebuješ komplexnú funkčnosť a stačí ti obmedzená sada.

    To je na základě toho, že jsem si pár algoritmů zkusil napsat v C++ i v javě a zjistil jsem, že abych dostal v C++ lepší výkon, tak jsem musel řešit asi 10x víc věcí, optimalizovat atd. V javě lze z pohledu C++ proramátora dost prasit (čti využívat funkcionální principy jako konstantní objekty atd.), což sice vede na větší zátěž VM, ale ta je na to optimalizovaná a programátor se většinou může spolehnout, že to dopadne dobře.

    Samozřejmě jsou extrémní případy, kdy je nutný low level jazyk, ale v praxi se spíš setkávám s takovými C++ programátory, kteří optimalizují každou ptákovinu aniž vědí proč a bojí se, že by o to v javě přišli.

    Konkrétně jsem jeden takový C++ kód předhodil v jedné diskuzi a první co matlal udělal bylo, že přepsal předávání všech struktur na const &. Sice to na výkonu nezměnilo ani prd, ale měl z toho dobrý pocit.

  • 6. 12. 2018 11:29

    JSH (neregistrovaný)

    > Konkrétně jsem jeden takový C++ kód předhodil v jedné diskuzi a první co matlal udělal bylo, že přepsal předávání všech struktur na const &. Sice to na výkonu nezměnilo ani prd, ale měl z toho dobrý pocit.

    A zeptal ses, proč to udělal? Ono to IMO nebylo primárně kvůli výkonu. V c++ je idiomatické předávat const & vždycky když nemáš nějaké speciální požadavky. Stejně tak je idiomatické vracet hodnotou a ne jako pointer na nově alokovaný objekt. Pak v obou případech nemusí autor funkce opravdu řešit, jestli ty objekty budou na zásobníku nebo na haldě.

  • 6. 12. 2018 14:37

    KarelI

    > A zeptal ses, proč to udělal? Ono to IMO nebylo primárně kvůli výkonu...

    Neptal jsem se. Úkol byl urychlit to, takže předpokládám, že si myslel, že se to tím zrychlí. Prostě takový ten každodenní cargo cult, který u zažraných C++ programátorů vidím každou chvíli. Je nezajímá, že mají algoritmus O^4, oni chtějí ušetřit na předávání reference.

  • 6. 12. 2018 14:43

    JSH (neregistrovaný)

    Aha, takže neptal, nevíš, ale přijde ti ok prostě předpokládat že je to pitomec. No já myslím, že mi to stačí...

  • 6. 12. 2018 15:17

    KarelI

    Přijde ti v pořádku argumentovat tím, že mě cituješ slovy, které jsem nevyslovil?

    Řekl jsem, že je to matlal. Když někomu dám urychlit kus kódu (jednorázový, testovací), on tam udělá mraky změn ale přitom neurychlí vůbec nic, tak to splňuje definici matlala ať už jsou jeho záměry sebevznešenější. To znamená, že nemá smysl se ho ptát na důvody, protože případná odpověď nemá vliv na fakt, že řešil něco jiného než řešit měl.

    A tento příklad dobře ukázal, jak je programátor odváděn od problému a místo toho řeší specifika daného jazyka.

  • 6. 12. 2018 19:10

    JSH (neregistrovaný)

    > Přijde ti v pořádku argumentovat tím, že mě cituješ slovy, které jsem nevyslovil?

    Jak slovy, které jsem nevyslovil? Když ve svém textu nahradím "pitomec" za "matlal", tak mám skoro doslova to, co jsi tu napsal.

    Skoro se bojím hádat, jak mohlo vypadat to zadání. Podle toho, co tady kolem píšeš se bojím, že jsi typicky po Javovsku naalokoval mračna malých objektů (odhaduju podle poznámky o dynamicky alokovaném 3D vektoru). Pak se to zamozřejmě urychlit nedá. Tam není problém rychlost jazyka. Tam je problém, že žádné CPU nezvládá kód, který skáče po paměti jako divý. Tenhle přístup trestají všechny jazyky +- stejně, protože cache miss stojí +- stejně.

  • 6. 12. 2018 20:51

    KarelI

    Hele, vést diskuzi stylem “když za X dosadím Y...” nedává smysl. Pokud máš jiný názor, tak pro mě nemá smysl pokračovat.

    V C++ byly instance na stacku, v javě to jinak než na heapu nejde a přesto to cache miss nezabil.

  • 6. 12. 2018 17:20

    echo zulu (neregistrovaný)

    > čti využívat funkcionální principy jako konstantní objekty atd
    To sa predsa dá aj v C++
    Okrem toho, šablónové metaprogramovanie je vlastne funkcionálne programovanie

    > Samozřejmě jsou extrémní případy, kdy je nutný low level jazyk
    Stačí ak píšeš pre platformu, ktorú nemáš pod kontrolou a pre ktorú nemáš inú možnosť.

    > s takovými C++ programátory, kteří optimalizují každou ptákovinu
    To sa týka programátorov, nie jazyka, takí sú všade a v každom obore :-)

    > a bojí se, že by o to v javě přišli
    Nemusí ísť iba o jazyk samotný, ale aj ekosystém, knižnice, atď., je v tom veľa know-how, ktorý sa neoplatí zahodiť len kvôli tomu, že sa niečo môže zdať niekomu nepohodlné.

  • 6. 12. 2018 18:28

    KarelI

    Konstantní se dají i v C++, ale protože tato technika vede na více alokací, tak to v C++ dříve narazí na limity.

    Např. u takového Vector3D ve kterém je 3x double, kdybych výsledky základních operací dělal jako nové instance, tak mě to v C++ hodně rychle vytrestá.

  • 4. 12. 2018 21:58

    Tomas Z (neregistrovaný)

    Negeneralizovat. Nejstarsim GC jazykem je asi Lisp, a treba Common Lisp ma direktivu dynamic-extent, ktera hintuje kompilatoru ze ma stacl pouzit pokud to jde (a ma ji od roku 89 nebo tak nejak). A treba implementace sbcl ma funkce na testovani kde se opravdu alokuje.

  • 4. 12. 2018 9:51

    Ondra Satai Nekola
    Zlatý podporovatel

    No shit, Sherlock. Java se nehodí na úplně všechno!