Optimalizace programu - Program optimization

V informatice , optimalizaci programu , optimalizace kódu, nebo optimalizace softwaru je proces modifikace softwarový systém, aby se nějaký aspekt z toho pracovat efektivněji nebo použít méně prostředků. Obecně platí, že počítačový program může být optimalizovány tak, aby se spustí rychleji, nebo aby bylo schopné pracovat s menší pamětí nebo jiných zdrojů, nebo čerpat méně energie.

Všeobecné

Ačkoli slovo „optimalizace“ sdílí stejný kořen jako „optimální“, je jen vzácné, aby proces optimalizace vytvořil skutečně optimální systém. Systém lze obecně optimalizovat nikoli v absolutních termínech, ale pouze s ohledem na danou metriku kvality, která může být v kontrastu s jinými možnými metrikami. V důsledku toho bude optimalizovaný systém obvykle optimální pouze v jedné aplikaci nebo pro jedno publikum. Dalo by se snížit množství času, které program potřebuje k provedení nějakého úkolu, za cenu toho, že spotřebuje více paměti. V aplikaci, kde je paměťový prostor za příplatek, by člověk mohl záměrně zvolit pomalejší algoritmus , aby využil méně paměti. Často neexistuje design „jedna velikost pro všechny“, který by fungoval dobře ve všech případech, takže inženýři dělají kompromisy, aby optimalizovali atributy největšího zájmu. Navíc úsilí potřebné k tomu, aby byl software zcela optimální - neschopný jakéhokoli dalšího vylepšení - je téměř vždy větší, než je přiměřené pro výhody, které by se nahromadily; takže proces optimalizace může být zastaven před dosažením zcela optimálního řešení. Naštěstí se často stává, že největší vylepšení přichází na začátku procesu.

I pro danou metriku kvality (například rychlost provádění) většina metod optimalizace pouze zlepšuje výsledek; nemají předstírání, že produkují optimální výstup. Superoptimalizace je proces nalezení skutečně optimálního výstupu.

Úrovně optimalizace

Optimalizace může probíhat na několika úrovních. Vyšší úrovně mají obvykle větší dopad a je obtížnější je později v projektu změnit, což vyžaduje výrazné změny nebo úplné přepsání, pokud je třeba změnit. Optimalizace tedy může typicky probíhat prostřednictvím upřesnění z vyššího na nižší, přičemž počáteční zisky jsou větší a dosažené s menším množstvím práce a pozdější zisky jsou menší a vyžadují více práce. V některých případech však celkový výkon závisí na výkonu velmi nízkoúrovňových částí programu a malé změny v pozdní fázi nebo včasné zvážení podrobností nízké úrovně mohou mít velký dopad. Typicky je v rámci projektu věnována určitá pozornost účinnosti - i když se to výrazně liší - ale hlavní optimalizace je často považována za vylepšení, které je třeba provést pozdě, pokud vůbec. U déle běžících projektů obvykle existují cykly optimalizace, kde zlepšení jedné oblasti odhaluje omezení v jiné, a ty jsou obvykle omezeny, když je výkon přijatelný nebo zisky příliš malé nebo nákladné.

Protože výkon je součástí specifikace programu-program, který je neobvykle pomalý, není vhodný pro daný účel: videohra se 60 Hz (snímky za sekundu) je přijatelná, ale 6 snímků za sekundu je nepřijatelně trhaná- výkon je zvážení od samého začátku, aby se zajistilo, že je systém schopen poskytovat dostatečný výkon, a rané prototypy musí mít zhruba přijatelný výkon, aby byla jistota, že konečný systém (s optimalizací) dosáhne přijatelného výkonu. To je někdy vynecháno ve víře, že optimalizaci lze vždy provést později, což má za následek prototypové systémy, které jsou příliš pomalé - často o řád nebo více - a systémy, které jsou v konečném důsledku selhání, protože architektonicky nemohou dosáhnout svých výkonnostních cílů, jako je jako Intel 432 (1981); nebo takové, které vyžadují roky práce k dosažení přijatelného výkonu, například Java (1995), která dosáhla přijatelného výkonu pouze pomocí HotSpot (1999). Míra, do jaké se mění výkonnost mezi prototypem a výrobním systémem, a jak je přístupná optimalizaci, může být významným zdrojem nejistoty a rizika.

Úroveň designu

Na nejvyšší úrovni může být design optimalizován tak, aby co nejlépe využíval dostupné zdroje, dané cíle, omezení a očekávané využití/zatížení. Architektonický návrh systému v drtivé většině ovlivňuje jeho výkon. Například systém, který je vázán na latenci sítě (kde latence sítě je hlavním omezením celkového výkonu), by byl optimalizován tak, aby se minimalizovaly výpadky sítě, ideálně by se jedna žádost (nebo žádné požadavky, jako v push protokolu ) místo více zpáteční lety. Volba designu závisí na cílech: je-li při navrhování překladače klíčovou prioritou rychlá kompilace, je jednoprůchodový překladač rychlejší než víceprůchodový (za předpokladu stejné práce), ale pokud je cílem rychlost výstupního kódu, pomalejší víceprůchodový kompilátor splňuje cíl lépe, i když to samo trvá déle. Volba platformy a programovacího jazyka probíhá na této úrovni a jejich změna často vyžaduje úplné přepsání, ačkoli modulární systém může umožnit přepsání pouze některé komponenty-například program Python může přepsat výkonově kritické sekce v C. systému, volba architektury ( klient-server , peer-to-peer atd.) probíhá na úrovni návrhu a může být obtížné ji změnit, zvláště pokud nelze všechny součásti synchronizovaně nahradit (např. staré klienty).

Algoritmy a datové struktury

Vzhledem k celkovému designu přichází na řadu dobrá volba efektivních algoritmů a datových struktur a efektivní implementace těchto algoritmů a datových struktur. Po návrhu výběr algoritmů a datových struktur ovlivňuje efektivitu více než kterýkoli jiný aspekt programu. Datové struktury se obecně obtížněji mění než algoritmy, protože předpoklad datové struktury a předpoklady jejího výkonu se používají v celém programu, ačkoli to lze minimalizovat použitím abstraktních datových typů v definicích funkcí a ponecháním omezených definic konkrétní datové struktury na několik míst.

U algoritmů to primárně spočívá v zajištění, že algoritmy jsou konstantní O (1), logaritmické O (log n ), lineární O ( n ) nebo v některých případech log-lineární O ( n log n ) na vstupu (oba v prostoru a čas). Algoritmy s kvadratickou složitostí O ( n 2 ) se nedaří škálovat a dokonce i lineární algoritmy způsobují problémy, pokud jsou opakovaně volány, a pokud je to možné, jsou obvykle nahrazeny konstantními nebo logaritmickými.

Kromě asymptotického pořadí růstu záleží na konstantních faktorech: asymptoticky pomalejší algoritmus může být rychlejší nebo menší (protože jednodušší) než asymptoticky rychlejší algoritmus, když jsou oba konfrontováni s malým vstupem, což může být případ, který se vyskytuje ve skutečnosti. Hybridní algoritmus často poskytne nejlepší výkon, protože tento kompromis se mění s velikostí.

Obecnou technikou ke zlepšení výkonu je vyhýbat se práci. Dobrým příkladem je použití rychlé cesty pro běžné případy, zlepšení výkonu tím, že se vyhnete zbytečné práci. Například pomocí jednoduchého algoritmu rozložení textu pro latinský text se přepnete pouze na složitý algoritmus rozložení pro složité skripty, jako je Devanagari . Další důležitou technikou je ukládání do mezipaměti, zejména memoizace , která se vyhýbá nadbytečným výpočtům. Z důvodu důležitosti ukládání do mezipaměti v systému často existuje mnoho úrovní ukládání do mezipaměti, což může způsobit problémy s využitím paměti a problémy se správností ze zastaralých mezipamětí.

Úroveň zdrojového kódu

Kromě obecných algoritmů a jejich implementace na abstraktním stroji mohou volby na úrovni konkrétního zdrojového kódu znamenat významný rozdíl. Například u raných kompilátorů C while(1)byl pomalejší než for(;;)u bezpodmínečné smyčky, protože while(1)vyhodnotil 1 a poté měl podmíněný skok, který otestoval, jestli je to pravda, zatímco for (;;)měl bezpodmínečný skok. Některé optimalizace (jako je tato) lze v dnešní době provádět optimalizací překladačů . To závisí na zdrojovém jazyce, cílovém strojovém jazyce a kompilátoru a může být obtížné jej pochopit nebo předvídat a v průběhu času se mění; toto je klíčové místo, kde porozumění kompilátorům a strojovému kódu může zlepšit výkon. Pohyby invariantního pohybu kódu a optimalizace návratové hodnoty jsou příklady optimalizací, které snižují potřebu pomocných proměnných a mohou dokonce vést k rychlejšímu výkonu tím, že se vyhnou optimalizacím kolem.

Úroveň stavby

Mezi úrovní zdroje a kompilace lze použít direktivy a příznaky sestavení k vyladění možností výkonu ve zdrojovém kódu respektive kompilátoru, jako například použití definic preprocesoru k deaktivaci nepotřebných funkcí softwaru, optimalizace pro konkrétní modely procesorů nebo hardwarové možnosti nebo předpovídání větvení , například. Systémy distribuce softwaru založené na zdrojích, jako jsou BSD 's Ports a Gentoo 's Portage, mohou využít této formy optimalizace.

Úroveň kompilace

Použití optimalizačního kompilátoru má tendenci zajistit, aby byl spustitelný program optimalizován alespoň tak, jak kompilátor dokáže předvídat.

Úroveň montáže

Na nejnižší úrovni může psaní kódu pomocí sestavovacího jazyka navrženého pro konkrétní hardwarovou platformu produkovat nejefektivnější a nejkompaktnější kód, pokud programátor využije celý repertoár strojových pokynů . Mnoho operačních systémů používaných na vestavěných systémech bylo z tohoto důvodu tradičně napsáno v kódu assembleru. Programy (jiné než velmi malé programy) se zřídka zapisují od začátku do konce v sestavě kvůli času a nákladům. Většina z nich je kompilována z jazyka na vysoké úrovni do sestavení a odtud optimalizována ručně. Když jsou účinnost a velikost méně důležité, mohou být velké části psány v jazyce na vysoké úrovni.

S modernějšími optimalizačními kompilátory a větší složitostí současných CPU je těžší napsat efektivnější kód, než jaký kompilátor generuje, a jen málo projektů potřebuje tento „konečný“ optimalizační krok.

Velká část kódu, který je dnes napsán, má běžet na co největším počtu počítačů. V důsledku toho programátoři a kompilátoři ne vždy využívají výhod efektivnějších pokynů poskytovaných novějšími CPU nebo vtípky starších modelů. Navíc kód sestavení vyladěný pro konkrétní procesor bez použití takových pokynů může být stále neoptimální na jiném procesoru a očekávat jiné vyladění kódu.

Programátoři dnes místo psaní v jazyce sestavení použijí disassembler k analýze výstupu kompilátoru a změně zdrojového kódu na vysoké úrovni tak, aby jej bylo možné kompilovat efektivněji, nebo pochopit, proč je neefektivní.

Doba běhu

Kompilátory just-in-time mohou vytvářet přizpůsobený strojový kód na základě údajů o běhu za cenu režijních nákladů na kompilaci. Tato technika pochází z prvních motorů regulárních výrazů a rozšířila se u Java HotSpot a V8 pro JavaScript. V některých případech může být adaptivní optimalizace schopna provést optimalizaci doby běhu, která překračuje možnosti statických kompilátorů dynamickým nastavením parametrů podle skutečného vstupu nebo jiných faktorů.

Optimalizace řízená profilem je optimalizační kompilační technika s předstihem (AOT) založená na profilech doby běhu a je podobná analogickému statickému „průměrnému případu“ dynamické techniky adaptivní optimalizace.

Samoobslužný kód se může sám změnit v reakci na podmínky běhu za účelem optimalizace kódu; toto bylo běžnější v programech jazyků sestavení.

Některé návrhy CPU mohou provádět určité optimalizace za běhu. Některé příklady zahrnují provádění mimo pořadí , spekulativní provádění , instrukční kanály a prediktory větví . Kompilátory mohou programu pomoci využít výhod těchto funkcí CPU, například prostřednictvím plánování instrukcí .

Optimalizace závislé na platformě

Optimalizaci kódu lze také široce kategorizovat jako na platformě závislé a na platformě nezávislé techniky. Zatímco ty druhé jsou účinné na většině nebo všech platformách, techniky závislé na platformě používají specifické vlastnosti jedné platformy nebo se spoléhají na parametry v závislosti na jediné platformě nebo dokonce na jediném procesoru. Proto může být zapotřebí zápis nebo produkce různých verzí stejného kódu pro různé procesory. Například v případě optimalizace na úrovni kompilace jsou technikami nezávislými na platformě obecné techniky (jako je rozvinutí smyčky , omezení volání funkcí, rutiny efektivní z hlediska paměti, snížení podmínek atd.), Které mají vliv na většinu architektur CPU v podobném způsob. Skvělý příklad optimalizace nezávislý na platformě byl ukázán s vnitřní pro smyčku, kde bylo pozorováno, že smyčka s vnitřní pro smyčku provádí více výpočtů za jednotku času než smyčka bez ní nebo smyčka s vnitřní zatímco smyčkou. Obecně tyto slouží ke snížení celkové délky cesty instrukce potřebné k dokončení programu a/nebo snížení celkového využití paměti během procesu. Na druhé straně techniky závislé na platformě zahrnují plánování instrukcí, paralelismus na úrovni instrukcí , paralelismus na úrovni dat, techniky optimalizace mezipaměti (tj. Parametry, které se liší mezi různými platformami) a optimální plánování instrukcí se může lišit i na různých procesorech stejná architektura.

Snížení síly

Výpočetní úlohy lze provádět různými způsoby s různou účinností. Efektivnější verze s ekvivalentní funkcí je známá jako snížení pevnosti . Zvažte například následující úryvek kódu C, jehož záměrem je získat součet všech celých čísel od 1 do N :

int i, sum = 0;
for (i = 1; i <= N; ++i) {
  sum += i;
}
printf("sum: %d\n", sum);

Tento kód lze (za předpokladu, že nedochází k přetečení aritmetiky ) přepsat pomocí matematického vzorce, jako je:

int sum = N * (1 + N) / 2;
printf("sum: %d\n", sum);

Optimalizace, někdy prováděná automaticky optimalizujícím kompilátorem, je vybrat metodu ( algoritmus ), která je výpočetně efektivnější, a přitom zachovat stejnou funkčnost. Diskuse o některých z těchto technik viz algoritmická účinnost . Významného zlepšení výkonu však lze často dosáhnout odstraněním nadbytečných funkcí.

Optimalizace není vždy zřejmý nebo intuitivní proces. Ve výše uvedeném příkladu by „optimalizovaná“ verze mohla být ve skutečnosti pomalejší než původní verze, pokud by N bylo dostatečně malé a konkrétní hardware by byl při provádění operací sčítání a smyčky mnohem rychlejší než násobení a dělení.

Kompromisy

V některých případech však optimalizace spoléhá na použití propracovanějších algoritmů, použití „zvláštních případů“ a speciálních „triků“ a provádění složitých kompromisů. „Plně optimalizovaný“ program může být obtížněji pochopitelný, a proto může obsahovat více chyb než neoptimalizované verze. Kromě eliminace zjevných antipattern snižují některé optimalizace na úrovni kódu udržovatelnost.

Optimalizace se obecně zaměří na zlepšení pouze jednoho nebo dvou aspektů výkonu: doba provádění, využití paměti, místo na disku, šířka pásma, spotřeba energie nebo nějaký jiný zdroj. To bude obvykle vyžadovat kompromis-kde je jeden faktor optimalizován na úkor ostatních. Například zvětšení velikosti mezipaměti zlepšuje výkon za běhu, ale také zvyšuje spotřebu paměti. Mezi další běžné kompromisy patří srozumitelnost a stručnost kódu.

Existují případy, kdy se programátor provádějící optimalizaci musí rozhodnout, aby byl software pro některé operace lepší, ale za cenu toho, že ostatní operace budou méně účinné. Tyto kompromisy mohou mít někdy netechnický charakter-například když konkurent zveřejnil výsledek benchmarku, který je třeba překonat, aby se zlepšil komerční úspěch, ale přichází možná s břemenem, který snižuje účinnost běžného používání softwaru. Takové změny jsou někdy žertem označovány jako pesimizace .

Úzká místa

Optimalizace může zahrnovat nalezení úzkého místa v systému - součást, která je limitujícím faktorem výkonu. Pokud jde o kód, bude to často hot spot  - kritická část kódu, který je primárním spotřebitelem potřebného zdroje - i když to může být další faktor, například latence I/O nebo šířka pásma sítě.

Ve výpočetní technice se spotřeba zdrojů často řídí formou distribuce energetického zákona a Paretův princip lze použít na optimalizaci zdrojů pozorováním, že 80% zdrojů je obvykle využíváno 20% operací. V softwarovém inženýrství je často lepší odhad, že 90% času spuštění počítačového programu je vynaloženo na vykonání 10% kódu (v této souvislosti známý jako zákon 90/10).

Složitější algoritmy a datové struktury fungují dobře u mnoha položek, zatímco jednoduché algoritmy jsou vhodnější pro malá množství dat - nastavení, doba inicializace a konstantní faktory složitějšího algoritmu mohou převážit nad výhodami, a tedy hybridní algoritmus nebo adaptivní Algoritmus může být rychlejší než jakýkoli jiný algoritmus. Profil výkonu lze použít ke zúžení rozhodování o tom, která funkce odpovídá jakým podmínkám.

V některých případech může přidání další paměti pomoci zrychlit běh programu. Například program pro filtrování běžně přečte každý řádek a filtruje a okamžitě vygeneruje tento řádek. To používá pouze dostatek paměti pro jeden řádek, ale výkon je obvykle špatný kvůli latenci každého čtení disku. Uložení výsledku do mezipaměti je podobně účinné, i když také vyžaduje větší využití paměti.

Kdy optimalizovat

Optimalizace může snížit čitelnost a přidat kód, který se používá pouze ke zlepšení výkonu . To může komplikovat programy nebo systémy, což ztěžuje jejich údržbu a ladění. V důsledku toho se optimalizace nebo ladění výkonu často provádí na konci vývojové fáze .

Donald Knuth učinil následující dvě prohlášení o optimalizaci:

"Měli bychom zapomenout na malou efektivitu, řekněme asi 97% případů: předčasná optimalizace je kořenem všeho zla. Přesto bychom neměli nechat ujít naše příležitosti v těch kritických 3%."

(Citát také připsal Tonymu Hoarovi o několik let později, i když to mohla být chyba, protože Hoare odmítá, že vytvořil frázi.)

„V zavedených technických oborech není 12% zlepšení, které lze snadno získat, nikdy považováno za okrajové, a domnívám se, že stejné hledisko by mělo převládat v softwarovém inženýrství“

„Předčasná optimalizace“ je fráze používaná k popisu situace, kdy programátor nechává úvahy o výkonu ovlivnit design části kódu. Výsledkem může být návrh, který není tak čistý, jak by mohl být, nebo kód, který je nesprávný, protože kód je komplikován optimalizací a programátor je rozptylován optimalizací.

Při rozhodování, zda optimalizovat konkrétní část programu, by měl být vždy brán v úvahu Amdahlův zákon : dopad na celkový program do značné míry závisí na tom, kolik času se v dané konkrétní části skutečně stráví, což není vždy jasné z pohledu na kód. bez analýzy výkonu .

Lepším přístupem je proto nejprve navrhnout kód z návrhu a poté profilovat / porovnat výsledný kód, abyste zjistili, které části by měly být optimalizovány. Jednoduchý a elegantní design je v této fázi často snazší optimalizovat a profilování může odhalit neočekávané problémy s výkonem, které by nebyly vyřešeny předčasnou optimalizací.

V praxi je při prvním návrhu softwaru často nutné mít na paměti výkonnostní cíle, ale programátor vyvažuje cíle návrhu a optimalizace.

Moderní kompilátory a operační systémy jsou tak účinné, že se zamýšlené zvýšení výkonu často nepodaří uskutečnit. Ukládání dat do mezipaměti na úrovni aplikace, která je znovu ukládána do mezipaměti na úrovni operačního systému, například nepřinese vylepšení při provádění. I přesto je to výjimečný případ, kdy programátor odstraní neúspěšné optimalizace z produkčního kódu. Je také pravda, že pokroky v hardwaru budou častěji obcházet všechna potenciální vylepšení, ale zatemňující kód bude přetrvávat do budoucnosti dlouho poté, co byl jeho účel negován.

Makra

Optimalizace během vývoje kódu pomocí maker nabývá různých forem v různých jazycích.

V některých procedurálních jazycích, jako je C a C ++ , jsou makra implementována pomocí nahrazování tokenů. V současné době lze inline funkce v mnoha případech použít jako alternativu bezpečnou pro typ . V obou případech může tělo vložené funkce poté projít další optimalizací v době kompilace kompilátorem, včetně konstantního skládání , což může přesunout některé výpočty do času kompilace.

V mnoha funkčních programovacích jazycích jsou makra implementována pomocí časově substituční analýzy analyzovaných stromů/abstraktních syntaxových stromů, o kterých se tvrdí, že je bezpečnější používat. Jelikož se v mnoha případech používá interpretace, je to jeden ze způsobů, jak zajistit, aby se takové výpočty prováděly pouze v čase analýzy, a někdy jediný způsob.

Lisp vznikl tímto stylem makra a taková makra se často nazývají „makra podobná Lispu“. Podobného efektu lze dosáhnout použitím metaprogramování šablon v C ++ .

V obou případech je práce přesunuta do doby kompilace. Rozdíl mezi makry C na jedné straně a makry podobnými Lisp a metaprogramováním šablon C ++ na straně druhé spočívá v tom, že tyto nástroje umožňují provádění libovolných výpočtů v době kompilace/času analýzy, zatímco rozšíření maker C neprovádí žádné výpočet a spoléhá se na schopnost optimalizátoru ji provést. Navíc C makra přímo nepodporují rekurze či iterace , takže nejsou Turing kompletní .

Jako u každé optimalizace je však často obtížné předvídat, kde takové nástroje budou mít největší dopad, než bude projekt dokončen.

Automatická a ruční optimalizace

Viz také Kategorie: Optimalizace kompilátoru

Optimalizace může být automatizována kompilátory nebo prováděna programátory. Zisky jsou obvykle omezené pro místní optimalizaci a větší pro globální optimalizace. Nejsilnější optimalizací je obvykle najít vynikající algoritmus .

Optimalizaci celého systému obvykle provádějí programátoři, protože je pro automatizované optimalizátory příliš složitý. V této situaci programátoři nebo správci systému výslovně změní kód, aby celkový systém fungoval lépe. Ačkoli to může přinést lepší účinnost, je to mnohem dražší než automatické optimalizace. Protože mnoho parametrů ovlivňuje výkon programu, je prostor pro optimalizaci programu velký. Metaheuristika a strojové učení se používají k řešení složitosti optimalizace programu.

Pomocí profileru (nebo analyzátoru výkonu ) najděte části programu, které spotřebovávají nejvíce prostředků - úzké místo . Programátoři někdy věří, že mají jasnou představu o tom, kde je úzké místo, ale intuice je často špatná. Optimalizace nedůležitého kusu kódu obvykle celkově nepomůže.

Když je úzké místo lokalizováno, optimalizace obvykle začíná přehodnocením algoritmu použitého v programu. Častěji než ne, může být konkrétní algoritmus specificky přizpůsoben konkrétnímu problému a přináší lepší výkon než obecný algoritmus. Například seřazení obrovského seznamu položek se obvykle provádí pomocí rutiny quicksort , což je jeden z nejefektivnějších generických algoritmů. Pokud je však některá charakteristika položek využitelná (například jsou již uspořádány v určitém konkrétním pořadí), lze použít jinou metodu nebo dokonce vlastní třídící rutinu.

Poté, co si je programátor přiměřeně jistý, že je vybrán nejlepší algoritmus, může začít optimalizace kódu. Smyčky lze rozvinout (pro nižší smyčku nad hlavou, i když to často může vést k nižší rychlosti, pokud přetěžuje mezipaměť CPU ), lze použít datové typy co nejmenší, místo plovoucí desetinné čárky lze použít celočíselnou aritmetiku atd. . ( Pro tyto a další techniky viz článek o algoritmické účinnosti .)

Úzká místa výkonu mohou být způsobena spíše jazykovými omezeními než algoritmy nebo datovými strukturami používanými v programu. Někdy může být kritická část programu přepsána do jiného programovacího jazyka, který poskytuje přímější přístup k základnímu počítači. Například je velmi běžné, že jazyky velmi vysoké úrovně, jako je Python , mají moduly napsané v jazyce C pro vyšší rychlost. Programy již napsané v jazyce C mohou mít moduly zapsané v sestavení . Programy napsané v D mohou používat vložený assembler .

Přepisování sekcí se za těchto okolností „vyplatí“ kvůli obecnému „ pravidlu “ známému jako zákon 90/10 , který říká, že 90% času je věnováno 10% kódu a pouze 10% času ve zbývajících 90% kódu. Vkládání intelektuálního úsilí do optimalizace jen malé části programu může mít obrovský vliv na celkovou rychlost - pokud lze najít správnou část (části).

Ruční optimalizace má někdy vedlejší účinek oslabení čitelnosti. Optimalizace kódu by proto měla být pečlivě zdokumentována (nejlépe pomocí přímých komentářů) a vyhodnocen jejich vliv na budoucí vývoj.

Program, který provádí automatizovanou optimalizaci, se nazývá optimalizátor . Většina optimalizátorů je vložena do kompilátorů a pracuje během kompilace. Optimalizátory mohou často generovat kód na míru konkrétním procesorům.

Dnes jsou automatické optimalizace téměř výhradně omezeny na optimalizaci kompilátoru . Protože však optimalizace kompilátoru jsou obvykle omezeny na pevnou sadu poměrně obecných optimalizací, existuje značná poptávka po optimalizátorech, které mohou přijímat popisy optimalizací problémů a jazyků, což umožňuje inženýrovi specifikovat vlastní optimalizace. Nástroje, které přijímají popisy optimalizací, se nazývají systémy transformace programu a začínají být aplikovány na skutečné softwarové systémy, jako je C ++.

Některé jazyky na vysoké úrovni ( Eiffel , Esterel ) optimalizují své programy pomocí středně pokročilého jazyka .

Grid computing nebo distribuované výpočty mají za cíl optimalizovat celý systém přesunutím úloh z počítačů s vysokým využitím do počítačů s dobou nečinnosti.

Čas potřebný k optimalizaci

Někdy může být problém samotný čas potřebný k provedení optimalizace.

Optimalizace stávajícího kódu obvykle nepřidává nové funkce, a co je ještě horší, může přidat nové chyby v dříve fungujícím kódu (jako každá změna). Protože ručně optimalizovaný kód může mít někdy menší „čitelnost“ než neoptimalizovaný kód, může mít optimalizace dopad i na jeho udržovatelnost. Optimalizace má svou cenu a je důležité mít jistotu, že se investice vyplatí.

Automatický optimalizátor (nebo optimalizační kompilátor , program, který provádí optimalizaci kódu) může být třeba optimalizovat sám, a to buď za účelem dalšího zlepšení účinnosti svých cílových programů, nebo také za účelem zrychlení vlastní činnosti. Kompilace prováděná se „zapnutou“ optimalizací obvykle trvá déle, i když to je obvykle problém pouze v případě, že jsou programy poměrně velké.

Zejména u kompilátorů typu just-in-time je výkon komponenty kompilace doby běhu , provádějící společně se svým cílovým kódem, klíčem ke zlepšení celkové rychlosti provádění.

Reference

  • Jon Bentley : Efektivní psaní programů , ISBN  0-13-970251-2 .
  • Donald Knuth : Umění počítačového programování

externí odkazy