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 emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *