Inkrementální operátor a jeho rychlost

Dnešní článek je spíše zamyšlením, nad tím, co jako programátoři víme a máme ověřené vůči tomu, co si myslíme. Kdysi dávno celou řadu z nás učili, že pokud použijeme inkrementální operátor v jeho prefix formě, bude výkon aplikace vyšší.

Prefix forma je uvedena na příkladu níže (++i)

To, že bude výkon vyšší většina ‚školitelů‘ vykládá tím, že v přímém přepisu do jazyka assembler, je hodnota, která má být vrácena je nejdříve zvýšena o jednotku a až poté přímo navrácena. Zatímco v případě opačném, tedy suffix formě je nutné vytvořit lokální pomocnou proměnnou, do které se uloží předchozí hodnota, která se má navrátit. Teprve poté je možné tuto hodnotu (proměnnou) zvětšit o jednu jednotku.

Pokud i vám toto někdy někdo říkal, samozřejmě měl pravdu, nicméně ve chvíli, kdy se nepíše program přímo v jazyce assembler, ale například v jazyce C, nebo C++, vstupuje do pomyslné hry ještě kompilátor. Vzhledem k tomu, že kompilátor je takové dost divné zvíře, které má právo naprosto zamíchat kartami, podíváme se mu trochu na zoubek.

Naivní představa, jak toto otestovat spočívá v tom, že si programátor napíše dva obdobné programy a v jednom z nich použije suffix formu, ve druhém prefix formu a následně porovná dobu běhu. Tato představa je naivní především proto, že do výsledného času běhu se promítne i zbytek systému, který může využívat procesor velmi nestejnoměrně.

Lepší způsob a současně i zde prezentovaný postup spočívá v tom, že programátor rovněž vytvoří dva obdobné programy. Nicméně požádá kompilátor o to, aby zobrazil výsledný kód v jazyce assembler. Více o jazyce assemebler na wiki.

Následující kompilační příkaz požádá kompilátor o to, aby zobrazil výsledný kód v jazyce assembler.

Parametry předané kompilátoru:

  • -Os kompilátor provede optimalizaci s důrazem na výslednou velikost
  • -S výstupem kompilace bude soubor se stejným jménem, a bude obsahovat assembler kód

Výsledný zdrojový kód v jazyce assembler

Protože jsou oba výsledné zdrojové kódy v assembleru shodné, bude i vykonávaný program shodný.

Závěrem lze tedy říci, že kompilátor s příslušnými flagy (výsledek je stejný i bez -Os flagu) na architektuře x86 provede tuto optimalizaci za programátora. Je ovšem nutné upozornit čtenáře na to, že tyto výsledky platí pouze pro tento relativně jednoduchý příklad. Jak si kompilátor poradí v případě, že inkrementovaným objektem nebude číslo typu int, ale složitější datová struktura je otázkou pro další test.

Mohlo by se vám líbit...

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *