Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Rychlost výjimek

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: Rychlost výjimek

Autor: Sleeper

20:32:31 02.11.2011

Když se dva perou, třetí se směje :)
Hezká diskuze, díky M. Pankráci a RSTEINovi za přínosné informace!

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: AnonymousUser

20:13:25 03.04.2008

Pak bez problémů výjimky použijte, nevidím v tom problém.

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

7:14:58 03.04.2008

Eh, to mělo být
...
while(!(vstup_do_menu || QUIT))
...

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

7:12:01 03.04.2008

Mno šíleně náročný... to zas není, ale hraju si ve 3D a to prostě vyžaduje šetření výkonu, kde se dá. Pak taktéž uvažuju o programování na Nintendo DS a jako všechny jiné konzole, i zde je třeba šetřit výkonem dvojnásobně.

Konkrétně jde o hru (hm, zatím 3D bludiště :3) s tím, že v případě problému s pamětí (či jakémkoli jiném) je potřeba o tomto problému spravit hlavní cyklus jakoby "zvenčí", protože odsud je přístupná instance třídy s herním prostředím a tudíž bych se mohl ještě před konce programu v případě fatal chyby pokusit uložit dosavadní pokrok (do nějakého speciálního savu) aby hráč nepřišel o data. A právě odchycení výjímky mě přišlo nejvýhodnější, protože to mě dostane právě tak, kam chci v takovém případě. A volat tuto funkci přímo na místě se mě nechce, protože položky třídy nemají přístup k datám/metodám třídy, jíž jsou součástí a globální proměnnou se mě to zrovna 2x řešit nechce - začínám se držet heslem "čím míň globálních proměnných, tím líp" (to víte, dostala se mě pod ruku kniha Dokonalý kód (Code complete)). Mě jde prostě o rozdíl rychlostí (zkraceně a obrazně):

svet.hraj_a_vykresluj();

a

try
{
svet.hraj_a_vykresluj();
}
...


kde

hraj_a_vykresluj()
{
while(vstup_do_menu || QUIT)
{
hraj();
vykresli();
reload(); // prohozeni bufferu, vypocet fps atd.
}
}

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: AnonymousUser

22:52:41 02.04.2008

Chtělo by specifikovat, co se vlastně má dokázat. Ale jinak efektivita try bloků je vysoká, protože pro C++ je v podstatě každý blok myšleně uzavřen do try bloku. C++ dělá asi toto:


{ // začátek bloku
lokální proměnné;
kód;
} // konec bloku


Tak C++ to přeloží zhruba takto:

try
{
konstrukce_lokálních_proměnných;
kód
}
finally
{
destrukce_lokálních_proměnných;
}


Když si tedy představíte, že C++ z každého bloku udělá try/finally blok, tak je to přesně to co skutečně C++ vnitřně dělá. Souvisí to se základní koncepcí správy zdrojů a prostředků programu v C++ nazvaném RAII (Resource Acquisition Is Initialization).

Proto klidně můžete plýtvat try bloky kam chcete, protože vnitřně jich tam do strojového kódu stejně nasází i bez Vašeho zásahu C++ kompilátor něúrekom. A pokud chcete zaručit odklizení prostředků i při chybě je koncept RAII základní možnost.

Jinak ale je třeba taky trochu být rozumný - jak řekl kolega, chyby ošetřit hned jak je to možné a výjimky nejsou jediným možným prostředkem na správu chyb. Protože ale nevíme, co autor chce přesně udělat, tak není možné říci, zda jeho představa řešení je dobrá, nebo špatná.

Miloslav Ponkrác

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: JSH

22:06:38 02.04.2008

Mám jednu otázečku. Co je to za šíleně náročný program, že se ti vyplatí takhle propírat efektivitu výjimek?

Při používání výjimek platí to samé, co bez nich. Chyby ošetřuj hned, jak je možné je vyřešit. Pokud neexistuje jiné řešení, než vypsat chybu a skončit, pak bude stačit ten jeden vnější try blok.

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

20:51:01 02.04.2008

Heh, to se nám tu z toho vyvinula zajímavá diskuze :3.

Nicméně měl bych teda jeden dotaz: pořád se píše, že program (běžně, teď nemám na mysli 64bit Win apod.) je TÉMĚŘ stejně rychlý, tak bych se chtěl zeptat, jak moc dobrý nápad by pak byl vložit hlavní cyklus do jednoho bloku try; cyklus by byl v něm, takže při každém snímku by se z tohoto bloku nevyskakovalo, ale vše by se odehrávalo v něm. Není to zas tak důležité, jen by mě to umožnilo udělat "ulož co se dá, když dojde paměť". Snažím se to totiž psat tak, aby všechny inicializace a alokace byly před hlavním během - tudíž jejich pravděpodobnost by byla nízká.
Zpomalení v případě výskytu a zachycení výjimky zas takové starosti nedělá - za tu ochranu to stojí. A vstup do bloku try nepředpokládám větší náročnost, než alokace pár proměnných, stejně tak výstup...

Citovat příspěvek

 

RE: RE: RE: Rychlost vyjimek

Autor: RSTEIN

20:27:36 02.04.2008

A opravdu posledn věc: Abyste odbornikem na CLR zustal, zkuste se fakt podivat na CER a zjisitit, zda vase apodikticka tvrzeni plati.

"Proto třeba některé výjimky v .NETu (například při nedostatku paměti) - prostě začnou ignorovat catch bloky, protože principy .NETu vůbec neumožňují tuto situaci nějak zvládnout."

Ale styl diskuze ala zive je osvezujicm prvkem. Jsem rad, ze u MVP stále v diskuzich plati - kurtoazie az na kost:) .

RS


Příspěvek zaslán emailem

Citovat příspěvek

 

RE: RE: RE: Rychlost vyjimek

Autor: RSTEIN

20:13:14 02.04.2008

Ja biju cernochy a Vy znate detailne a lepe.CLR. Kazdy mame svoji domenu. :)

RS

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: RE: RE: Rychlost vyjimek

Autor: AnonymousUser

20:08:00 02.04.2008

[ital]Pro CLR je práce se stackem metody vetsinou dost trivialni.[/ital]

Zatímco C++ nemusí se stackem u výjimek často pracovat vůbec. Ač i často pracuje. Ale třeba nemusí C++ například pořizovat záznam stacku jako to dělá CLR.


[ital]externi ulozene procedury v C++ v rukou prasackeho programatora slozily bez problemu cely server[/ital]

Nemáte pocit, že se toto netýká výjimek? Nevím proč, ale přijde mi to blbá argumentace ve stylu "A Vy zase zabíjíte černochy".

[ital]To jen na okraj k tomu, co jste rikal o prasackych yjimkach ve VB.NET. - pachat nepravosti muzete v jakemkoli jazyce a zneuzivat k tomu skoro kazdou konstrukci.[/ital]

Já jsem hlavně mluvil o komplexnosti obsluhy výjimek v catch blocích v .NET - a to platí. A tato komplexnost = zbytečně vyšší režie obsluhy výjimek v .NETu - polopaticky - zpomaluje to práci s výjimkami.

[ital]Mimochodem - rezie vyjimek v .Net při rozumnem pouziti vyjimek neprestavuje zadny problem ani v Compact .Net Frameworku.[/ital]

Na dnešních nadupaných počítačích ani pomalost většinou není problém. Nicméně to, že pomalost nepředstavuje (většinou) problém neznamená, že to prostě obecně v rámci .NETu není pomalejší.

[/ital]A alokace pameti pro tridu typu Exception je v .Net rychla a bezproblemova.[/ital]

A žádná alokace jako v C++ v případě výjimek je ještě daleko rychlejší, věřte mi. :-)

A dokonce žádná alokace je daleko bezproblémovější, než v .NETu, protože alokace je akce, která nemusí uspět a nemusí se povést. Prostě uvnitř .NETu nemáte ani tu záruku, že uspěje vyhození výjimky, zatímco při dobře napsaném a rozvrženém kódu v C++ tuto záruku dostanete.

Proto třeba některé výjimky v .NETu (například při nedostatku paměti) - prostě začnou ignorovat catch bloky, protože principy .NETu vůbec neumožňují tuto situaci nějak zvládnout. Zatímco v C++ se z nedostatku paměti (výjimce ::std::bad_alloc) můžete klidně dostat a dokonce i pokračovat v kódu.

[ital]ALe myslim, ze ve sporu nejsme.[/ital]

Jsme ve sporu a odporujeme si.

[ital]Diky za zajimavou diskuzi, abych uz tady nebyl OT, muzeme se nekdy pohadat (pokravovat v diskuzi) osobne v hospode. :)[/ital]

Prostě jste sem prásknul reklamní MS hlášku o úžasnosti .NETu, pak jste jich pár ještě přidal - bez konkrétních argumentů (čím to, že větší detaily o CLR a vnitřních mechanismech jsem tu uvedl já,než Vy), a když Vám začala hořet půda pod nohama, tak mluvíte o hospodě.

Citovat příspěvek

 

RE: RE: Rychlost vyjimek

Autor: RSTEIN

19:49:36 02.04.2008

Pane Miloslave Ponkraci (kdyz uz jsme tak fromalni) :),
reagoval jsem hlavne na tuto vetu:

"Protože zde v podstatě při vyhození výjimky nutně dochází k dost brutálním akcím - a neobjede se to bez dynamické alokace několika bloků paměti a často bez zásahu dost high level mechanismů, často i garbage collectoru."

1) Pro CLR je práce se stackem metody vetsinou dost trivialni. Pokud potrebuji robustni garance tykajici se stability kodu, mam dnes k dispozici CER (a diky nim uz se da při psani externich ulozenych procedur v MSSQL neusim tolik bat, ze mi někdo slozi cele SQL - externi ulozene procedury v C++ v rukou prasackeho programatora slozily bez problemu cely server. To jen na okraj k tomu, co jste rikal o prasackych yjimkach ve VB.NET. - pachat nepravosti muzete v jakemkoli jazyce a zneuzivat k tomu skoro kazdou konstrukci.

Ad MS pristup k vyjimkam) Od verze 1.0 se pouze odstranily nektere neprijemne chyby (tzv. hall of shame) a konecne si vyvojari MS davaji pozor a nepouzivaji mechanismus vyjimek třeba pro prenaseni informace v ruznych castech kodu, coz castecne nohlo třeba za nefunkcni bindinzvlastni gjednoduchych ovladacich prvku jako je textbox. Dále vymizely zabijacke sekce catch (Edxception e) pohlcujici vyjimku a tak dogmaticky se netrva na tom, ze klientsky kod by mel dedit z ApplicationException.

Mimochodem - rezie vyjimek v .Net při rozumnem pouziti vyjimek neprestavuje zadny problem ani v Compact .Net Frameworku. Z CNF jsem mel vetsi obavy a nepotvrdily se. A alokace pameti pro tridu typu Exception je v .Net rychla a bezproblemova. CLR je fakt uzasny nastroj :)

ALe myslim, ze ve sporu nejsme. Diky za zajimavou diskuzi, abych uz tady nebyl OT, muzeme se nekdy pohadat (pokravovat v diskuzi) osobne v hospode. :)

Zdravim
Rene Stein
http://blog.renestein.net




Příspěvek zaslán emailem

Citovat příspěvek

 

Re: RE: Rychlost vyjimek

Autor: AnonymousUser

19:06:53 02.04.2008

Pane René Stein, nesouhlasit můžete, ale tak to prostě je. Výjimky v .NETu a jejich režie je prostě mnohem větší, než co můžete docílit v C++.

Vyjádření MS není příliš přesné (a od té doby co třeba DRM a zhoršování kvality multimédií v jádře Vist MS prezentuje jako přidanou hodnotu pro uživatele) - a papír snese všechno. Navíc jste schválně zcela opomněl mojí poznámku, že výjimky jsou ve Windows 64 povinné! A tedy i .NET kód je povinnen mít nejen výjimky na úrovni CLR, ale také na úrovni strojového kódu (stejně jako to dělají v C++) - tedy zde bude docházet ke dvojité neefektivitě v managed kódu v rámci použití výjimek a C++ bude mít ještě daleko více značně navrch.

V C++ je složitější stack unwiding, ale dissasemblujte si libovolný kód z kvalitního C++ kompilátoru a budete překvapen, jak efektivně to C++ dělá. A při dobré optimalizaci kompilátoru je tato režie v řadě případů také nulová, protože jí není potřeba dělat vůbec, neboť situace to nevyžaduje.

Zajímavé je (detaily neznám, určitě bych je našel, ale Vy to budete znát lépe), že ze začátku MS důsledně v .NET frameworku používat výjimky - později při zjištění, jak pomalé výjikmy v .NETu dokážou být přidal v některých případech i alternativní metody vracející pouhé chybové kódy aby nedocházelo ke zbytečnému zpomalování programu.

Mohl bych se také zmínit o režii třídy System.Exception, která přestože je relativně jednoduchá nese spousty informací (což znamená na úrovni strojového kódu ty informace vytvořit, naalokovat pro ně bloky pamětí, zkopírovat nějaké informace, projet stack a zjistit další informace atd..) - většina výjimkových tříd v C++ má mnohonásobně menší režii, než samotná System.Exception. Podívejte se na ::std::exception v C++ a ta třída je velmi nenáročná s naprosto minimální režií a velmi efektivní.

Mohl bych se také zmínit o odlišné strategii při prohledávání bloků catch, která je v .NETu příliš obecná a zbytečně komplexní - a proto méně efektivní. Zatímco jazyk C++ důsledně hledá správný typ při hledání catch bloků, tak .NET vyžaduje pro každý catch blok existenci komplexních malých funkcí (tzv. funcletu), která vyhodnotí, zda daný catch je správný. Stejně to většina .NET jazyků vůbec neumí využít, například v C# to nejde, ale třeba ve VB.NET je možné catch blok pořádně zaprasit podmínkami v catch blocích.

Miloslav Ponkrác

Citovat příspěvek

 

RE: Rychlost vyjimek

Autor: RSTEIN

18:19:43 02.04.2008

Dobry den,
Souhlasim s tim, ze implementace vyjimek je dnes v C++ na slusne urovni, ale zasadne nesouhlasim s tim, ze v C# jsou vyjimky pomalejsi. Efektivni "Exception handling" byl jednim z hlavnich cilu pri navrhu CLR.

Literatury i testu je uz mnoho, takze namatkou:

"The counter records both handled and unhandled exceptions, and treats exceptions that are rethrown as new exceptions. .NET has been designed to have efficient exception handling. This is an improvement over C++ exceptions where stack unwinding, due to an exception, is expensive; however, the argument is that this expense is acceptable because exceptions are rare—they are "exceptional."

Zdroj: http://www.ddj.com/windows/184405878

To co jste rikal o GC apod. muze byt castecne pravda pri osetrovani nerizenych (unmanaged) vyjimek.

Zdravim
Rene Stein
http://blog.renestein.net

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: AnonymousUser

18:01:10 02.04.2008

Použití výjimek může program zpomalit i zrychlit. Výjimky pomalé nejsou a ani n praxi nedělají vnitřně vše, co popisujete, protože to není vždy potřeba.

Pokud máte běžný program, a jste programátor, který se důsledně stará o kontrolu chyb, pak typicky použití výjimek způsobuje rychlejší program, než při kontrole návratových hodnot funkcí. Jako bonus výjimky jsou schopny ošetřit i věci, které s návratovými kódy nedosáhnete, a většinou je program i přehlednější a méně chybový - výjimky totiž ani prase programátor nemůže ignorovat na rozdíl od návratových hodnot, protože se mu připomenou předčasným ukončením program, pokud na ně bude kašlat.

Jinak výjimky jsou dnes velmi rychlé a pokud výjimky není vyhozena, tak blok try/catch je v podstatě téměř stejně rychlý, jako ta část bez bloku. Pokud je výjimka vyhozena, pak rychlost záleží na okolnostech - a zde to má programátor hodně v rukách.

Na 64 bitových Windows třeba bude často program bez výjimek dokonce pomalejší, než s nimi, protože přímo ABI Windows přikazuje, že každá funkce (která není leaf) MUSÍ vytvořit kód pro obsluhu výjimek a zotavení se s výjimky, neboť Windows to vyžadují. V samotném jádře Windows (i 32 bitového) se totiž výjimky běžně vyhazují. Takže i když v kódu výjimky nepoužijete, tak kompilátor stejně jejich obsluhu vnitřně ve strojovém kódu vytvoří - protože musí - a to v jakémkoli programovacím jazyce (i v tom, který výjimky na úrovni syntaxe nepodporuje).

Výjimky jsou dnes super rychlé - od doby kdy začínaly se podařilo najít takovou implementaci, která v podstatě běží jako blesk. Dnes při implementaci kompilátory postupují tak, že se snaží maximalizovat rychlost programu při nevyhozené výjimce i za cenu, že vyhození výjimky a proces obsluhy výjimky proběhne o pár procent pomaleji.

O dost pomalejší mohou být třeba výjimky v takovém C#, nebo Javě, protože zde v podstatě při vyhození výjimky nutně dochází k dost brutálním akcím - a neobjede se to bez dynamické alokace několika bloků paměti a často bez zásahu dost high level mechanismů, často i garbage collectoru. Zde je pak režie dost vysoká - a někdy se vyplatí minimalizovat počet výjimek, chcete-li makat na rychlost. Ale v C++ jsou výjimky velmi rychlé a efektivní - pokud to programátor nezabije hodně nešikovným použitím a monstrózními třídami s obrovskou režií vyhazované jako výjimky.

Já osobně už kód bez výjimek nepíšu - a výjimky používám i v časově kritických programech - a pokud víte jak na to - téměř vždy došlo při použití výjimek ke zrychlení běhu programu.

Miloslav Ponkrác

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

17:04:20 02.04.2008

Oki, díky za pomoc, vám všem

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: JSH

16:43:30 02.04.2008

Vyjímky obvykle program zpomalují minimálně. Je to na úkor rychlosti při jejich skutečném vyhození. Někdy může být použití vyjímek i rychlejší, než neustálá kontrola návratových hodnot.
Na windowsech se o výjimky stará systém, takže ani moc nezáleží na překladači. Jak je to na linuxu netuším.

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

13:59:21 02.04.2008

Fakt? Tak to mám asi staré informace - četl jsem že je to jen experimentálně (pro zápis). Mno, pokud to funguje, tím líp ;). A funguje i komprese? (I když to by nebylo zas tak klíčové - jen tak pro informaci (Pokud ne, Winy by byly "program pro kompresi disku :3") )


Mimochodem, taky by mě zajímaly ty výjímky :3. Nevíte, kde jinde bych to mohl zkusit zjistit?

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: zitmen

13:28:06 02.04.2008

ntfs-3g funguje naprosto spolehlive

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

11:47:15 02.04.2008

Ale víš co? Ten odkaz na ty fora mě, pls, pošli, určitě se nakonec bude hodit...

(Než úplně přejdu na Linux taky musím vyřešit systém souborů - teď používám NTFS a jeho komprese je VELMI užitečná, kdežto v Linuxu je zápis prý jen experimentální a hrozí poškození dat... a bez komprese se mě ta data do PC prostě nevlezou (mám noťas jakožto i moje hlavní pracovní centrum :/ ) )

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

22:19:24 01.04.2008

Tož mám něco podobného - distribuci Ubuntu - teď si nevzpomínám jak se nazývá rozhraní, které používá (Gnome? Fakt si nejsem jist), ale je to s KDE podobné...

Tož - příkazovou řádku jsme se trošku učili ve škole a fakt jsem se s bashem nespřátelil...

Spíš mám tak trochu problém s tím, že jsem především na netu přes WiFi se složitým VPN nastavením a ještě jsem se s Linuxem s nastavením sítí nějak nespřátelil - přeci jen to funguje jinak než na Linuxu a metoda pokus-omyl mě moc nepomohla :3

Citovat příspěvek

 

Re: Rychlost vyjimek

Autor: jobes1

22:13:46 01.04.2008

Dňa Tuesday 01 April 2008 21:51:56 ste napísal:
> Heh, díky, ale zatím ten Linux zas tak moc nespěchá - jsem na VŠ a s
> Linuxem nemám takřka žádné zkušenosti, jen ty, které mě říkají, že učení se
> práce na něm bude nadlouho - a teď toho času zas tolik nemám...

za pol roka si avyslak na prikazovom riadku ;) ale naozaj to zaqbere vela
casu, ked nemas dobry hardware... ak mas dobry za jeden den to nastavis podla
navodov... ak mas prostredie KDE nebude tazke prejst z win na lin... staci
prejst WIKI aby si neco o tom vedel a mozes programovat ako na windowse ;)
pre obycajneho uzivatela to nebude problem prejst, tomu staci openoffice a
mozilla

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Rychlost výjimek

Autor: Laethnes

21:51:55 01.04.2008

Heh, díky, ale zatím ten Linux zas tak moc nespěchá - jsem na VŠ a s Linuxem nemám takřka žádné zkušenosti, jen ty, které mě říkají, že učení se práce na něm bude nadlouho - a teď toho času zas tolik nemám...

Citovat příspěvek

 

Re: Rychlost vyjimek

Autor: jobes1

21:48:02 01.04.2008

> (Mimochodem, používám Dev-C++, tady je to jak? Ano, vím, že je to zastaralé
> a už hledám náhradu (uvažuju o Linuxu).)
na linuxe funguje code::block ale neodporucam, racej kdevelop... su aj ine, ak
chces viac info napis sem, poslem ti na jabber meno miestnosti a serveru kde
sa rozobera programovanie na linuxe

s hlavnou otazkou nevem pomoct



Příspěvek zaslán emailem

Citovat příspěvek

 

Rychlost výjimek

Autor: Laethnes

21:40:26 01.04.2008

Ahojte,
chtěl bych se zeptat, jak je to s rychlostí výjimek, protože různé zdroje říkají různé věci. Je mě jasné, že to hodně záleží na implementaci v kompilátoru, ale nějaké obecné informace by byly, ne?

Někde jsem četl, že by to mělo fungovat tak, že při vytvoření bloku try-catch se prostě uloží data do zásobníku a teprve až při vyvolání výjimky dojde k postupnému odmazávání zásobníku (což se děje běžně při ukončení funkce), dokud to nenarazí na blok try a tam se pokusí najít příslušný blok catch. Jinde jsem ale četl, že už vše, co je v bloku try je poněkud zpomalováno. (To, že každý vstup a výstup do/z bloku try-catch zpomaluje je mě jasné, ale asi to nebude o moc horší, než volání funkce, ne?)

Mimochodem, samotné throw je velmi namáhavé (oproti return) proto, že musí promazávat při kompilaci neznámý počet dat v zásobníku, uvažuju správně?

Mno, takže jak to je? (Jde o to, že uvažuji do bloku try vložit hlavní cyklus programu s tím, že z něj nebude vystupovat v každém snímku, ale jen v opravdu rapidních případech změny programu - např. přejít z herního prostředí do menu)

(Mimochodem, používám Dev-C++, tady je to jak? Ano, vím, že je to zastaralé a už hledám náhradu (uvažuju o Linuxu).)

Moc děkuji

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: