1 / 40

Optimalizace algoritmů

Optimalizace algoritmů. Jiří „Fila“ Filipovič PUPworX. Předmět přednášky. časová složitost algoritmu význam často používané metody snižování složitosti lineární optimalizace kdy a kde optimalizovat základní metody, pro pokročilé asi nic nového…. Složitost algoritmu.

ivor-hale
Download Presentation

Optimalizace algoritmů

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Optimalizace algoritmů Jiří „Fila“ Filipovič PUPworX

  2. Předmět přednášky • časová složitost algoritmu • význam • často používané metody snižování složitosti • lineární optimalizace • kdy a kde optimalizovat • základní metody, pro pokročilé asi nic nového…

  3. Složitost algoritmu • teorie složitosti je velmi komplexní, bude demonstrován jen velmi zúžený pohled • složitostní třída popisuje chování algoritmu vzhledem k délce vstupu • časová vs. prostorová složitost • nejlepší, nejhorší a průměrný případ • zajímá nás asymptotické chování funkce složitosti

  4. Vlastnosti složitostních tříd • abstrahujeme od konkrétního času běhu algoritmu • nezávislost na CPU, kompilátoru… • O(g) – třída funkcí rostoucích nejvýše tak rychle jako g • Zajímá nás asymptotické chování • T(log2 n) = O(log n) • T(3n + 1) = O(n) • T(n2 - n + 3) = O(n2)

  5. Tabulka časů

  6. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; }

  7. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; } • jaká je časová složitost?

  8. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; } • jaká je časová složitost? • nejlepší případ O(1)

  9. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; } • jaká je časová složitost? • nejlepší případ O(1) • nejhorší případ O(n)

  10. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; } • jaká je časová složitost? • nejlepší případ O(1) • nejhorší případ O(n) • průměr O(n/2) – za jakých předpokladů?

  11. Určení složitosti - příklad • vyhledání prvku v poli int hledejSekvencne(int pole[n], int prvek){ for (int i = 0; i < n; i++) if (pole[i] == prvek) return i; return -1; } • jaká je časová složitost? • nejlepší případ O(1) • nejhorší případ O(n) • průměr O(n/2) – za jakých předpokladů? • jde to rychleji?

  12. Určení složitosti - příklad int hledejBinarne(int pole[n], int prvek){ int leva = 0; int prava = n; while (leva <= prava){ int stred = (prava-leva)/2 + leva; if (prvek > pole[stred]) leva = stred + 1; else if (prvek < pole[stred]) prava = stred - 1; else return stred; } return -1; }

  13. Určení složitosti - příklad int hledejBinarne(int pole[n], int prvek){ int leva = 0; int prava = n; while (leva <= prava){ int stred = (prava-leva)/2 + leva; if (prvek > pole[stred]) leva = stred + 1; else if (prvek < pole[stred]) prava = stred - 1; else return stred; } return -1; } • časová složitost O(log n)

  14. Snížení čas. složitosti • některé metody jsou genericky využitelné v mnoha problémech: • předpočítávání • stromy • hashe • heuristiky • aproximace

  15. Předpočítávání • použitelné pokud se pohybujeme v relativně malé množině hodnot, které je složité získat • typický případ snížení časové složitosti na úkor složitosti prostorové • časová složitost O(1) • prostorová je úměrná velikosti předpočítaných dat • pozor – cache miss je řádově 100x pomalejší než běžná instrukce – něco je dnes snazší počítat, než načítat z RAM

  16. Předpočítávání - příklady • goniometrické funkce • Pro nižší přesnost (předpočítá se omezený počet úhlů) • dnes je levnější aproximace Taylorovým rozvojem • vesmírný simulátor • realistické gravitační pole • předpočítávání viditelnosti • PVS • bourání domů • složitá fyzika počítána v čase t+n

  17. Stromy • běžné užití • vyhledávání prvku (O(log n)) • setřídění (O(n log n)) • při modifikaci problém vyvažování • nevyvážený strom ztrácí požadované vlastnosti • užití: • setřídění pole čísel, nalezení čísla • vytvoření prostorové hierarchie • vytvoření obálkové hierarchie

  18. Stromy - ukázka

  19. Stromy - ukázka

  20. Hashe • vyhledávání v relativně malé množině prvků z velké domény • slovníky • prostorové umístění těles • hesla • aj. • cíl – obvykle redukovat složitost vyhledávání na O(1)

  21. Hashovací funkce • mapuje vstupní klíč do indexu tabulky • hodnoty musí být mapovány rovnoměrně a náhodně • pokud má více klíčů stejný hash, prohledávají se tyto hashe sekvenčně (nebo je třeba je setřídit) • nalezení dobré hashovací funkce je někdy složité až nemožné (stojíme před úkolem zajistit náhodné mapování nenáhodných dat) • hashovací funkci často hledáme pokusem a omylem, některé operace se obecně hodí, využíváme velkých prvočísel

  22. Příklad – hashování prostoru • metoda pro první fázi detekce kolizí • prostor je rozdělen regulární mřížkou, podle polohy na mřížce lze zakódovat umístění těles • potenciálně kolidují tělesa se objeví na stejných indexech tabulky • výhodné při velkém množství pohybujících-se objektů • blíží se O(n) • zpomaluje nevhodná velikost mřížky, malá tabulka

  23. Příklad hashování prostoru • Červený objekt se zahashuje do 0000 • Modrý do 0010 a 0110 • Žlutý do 0101 a 0110 • Zelený do 0100, 0101, 1000 a 1001 • Jsou detekovány potenciální kolize: • Modrý x žlutý • Žlutý x zelený

  24. Hashovací tabulka

  25. Heuristiky • „ořezávání“ nezajímavých větví výpočtu • problém s nalezením vhodných kritérií • kterou větev zahodit, když nevidíme budoucnost? • užití např. • u pathfindingu (zahazování drahých cest) • v deskových hrách (zahazování nevýhodných tahů)

  26. Aproximace • nalezení přibližného výsledku • někdy nutnost (fyzika), někdy výrazná časová úspora (LOD, předpočítávání spojitých funkcí, heuristiky) • problém obchodního cestujícího: • O(n!) • Pomocí GA – počítáme dokud chceme lepší výsledek

  27. Lineární optimalizace • optimalizace „na úrovni programových řádků“ • zůstáváme v téže složitostní třídě, rychlost zvyšujeme pouze násobkem • je dobré znát náročnost běžných programových konstrukcí • je dobré znát hardware, na kterém program poběží • je dobré znát programové prostředí, náročnost knihovních funkcí atd.

  28. Volání funkcí • volání funkcí představuje určitou režii • kompilátor umí sám rozhodnout, která funkce bude linkována inline • rychlost volání funkce závisí na počtu a velikosti(!) parametrů • velká data je vhodnější předávat odkazem • virtuální metody jsou pomalejší • Nepoužívejte pozdní vazbu u jednoduchých a často volaných metod

  29. Výkonnost hardware • elementární aritmetické operace +, - a * jsou velmi rychlé, a to i v plovoucí řádové čárce • neceločíselné dělení je o řád pomalejší • goniometrické funkce jsou pomalejší než dělení • některé operace lze vektorizovat • paměť je škálována – registry, L2 cache, RAM, HDD… • někdy je lepší počítat, než „sahat“ do paměti

  30. Odstranění rekurze • rekurze je drahá • (pře)plnění zásobníku • režie s voláním a předáváním parametrů • některé algoritmy jsou v iterační formě špatně čitelné • neexistuje obecný návod, jak rekurzi odstranit

  31. Odstranění rekurze - příklad unsigned faktorial(unsigned x){ if (x == 0) return 1; else return x*faktorial(x-1); }

  32. Odstranění rekurze - příklad unsigned faktorial(unsigned x){ if (x == 0) return 1; else return x*faktorial(x-1); } unsigned faktorialOpt(unsigned x, unsigned p = 1){ if (x == 0) return p; else return faktorialOpt(x-1, x*p); }

  33. Kdy optimalizovat? • optimalita kódu je nepřímo úměrná jeho čitelnosti • nesoustřeďte se na kód na úrovni programových řádků, hledejte úzká hrdla • někdy je úzké hrdlo zjevné • někdy zjevné není • nepočítali jsme s tím, že se daný kód volá tak často • některá funkce trvá déle, než jsme si mysleli • přehlédli jsme zbytečné volání či nezoptimalizovanou funkci • je dobré používat profiler – najde chyby rychleji než my

  34. Kdy neoptimalizovat? • často optimalizujeme ze zvyku i tam, kde to není nutné • existují třídící algoritmy v O(n2) a O(n log n), má smysl o tom uvažovat u setřídění listiny vítězů, kterých je max. 20? • pozná někdo co dělá toto? while(*s++ = *t++);

  35. Kdy neoptimalizovat? • často optimalizujeme ze zvyku i tam, kde to není nutné • existují třídící algoritmy v O(n2) a O(n log n), má smysl o tom uvažovat u setřídění listiny vítězů, kterých je max. 20? • pozná někdo co dělá toto? while(*s++ = *t++); • nemachrujte – nikdy nevíte, kdo to po vás bude číst!

  36. Kdy neoptimalizovat? • často optimalizujeme ze zvyku i tam, kde to není nutné • existují třídící algoritmy v O(n2) a O(n log n), má smysl o tom uvažovat u setřídění listiny vítězů, kterých je max. 20? • pozná někdo co dělá toto? while(*s++ = *t++); • nemachrujte – nikdy nevíte, kdo to po vás bude číst! • neoptimalizujte části kódu, které se volají současně s výrazně náročnější operací • šetření času CPU při načítání z disku (ovšem pokud nejedete multivláknově) • výpočty před/po dlouhým cyklem

  37. Profiler • dynamická analýza výkonnosti programu • měří, kolik času tráví CPU v jednotlivých funkcích, jak často je volá • obvykle umožňuje přímo diassemblovat jednotlivé řádky kódu • dobře použitelný u zpracování dat s nízkou úrovní paralelizace • je dobré připravit profileru různé „scénáře“

  38. Ukázka

  39. Dotazy?

  40. Děkuji za pozornost.

More Related