Koodin optimointi

määritelmä ja ominaisuudet

koodin optimointi on mikä tahansa menetelmä koodin muokkaamiseksi koodin laadun ja tehokkuuden parantamiseksi. Ohjelma voidaan optimoida niin, että se tulee pienempi koko, Kuluttaa vähemmän muistia, suorittaa nopeammin, tai suorittaa vähemmän tulo/lähtö operaatioita.

perusvaatimukset optimointimenetelmien tulee noudattaa, on, että optimoidulla ohjelmalla on oltava sama teho ja sivuvaikutukset kuin optimoimattomalla versiolla. Tämä vaatimus voidaan kuitenkin jättää huomiotta siinä tapauksessa, että optimoinnin hyöty arvioidaan tärkeämmäksi kuin todennäköiset seuraukset ohjelman käyttäytymisen muutoksesta.

Optimointityypit ja-tasot

optimoinnin voivat suorittaa automaattiset optimoijat eli ohjelmoijat. Optimoija on joko erikoistunut ohjelmistotyökalu tai kääntäjän sisäänrakennettu yksikkö (ns.optimoiva kääntäjä). Nykyaikaiset prosessorit voivat myös optimoida koodiohjeiden suoritusjärjestyksen.

optimoinnit luokitellaan korkean ja matalan tason optimointeihin. Korkean tason optimoinnit suorittaa yleensä ohjelmoija, joka käsittelee abstrakteja kokonaisuuksia (toimintoja, menettelyjä, luokkia jne.) ja pitää mielessä tehtävän yleiset puitteet optimoida järjestelmän suunnittelu. Optimointeja suoritetaan tasolla alkeis rakennelohkojen lähdekoodi-silmukoita, haaroja, jne. – ovat yleensä kutsutaan korkean tason optimointeja liian, kun taas jotkut kirjoittajat luokittelevat ne erilliseen (“middle”) tasolle (N. Wirth?). Matalan tason optimoinnit suoritetaan siinä vaiheessa, kun lähdekoodi kootaan joukko koneen ohjeita, ja tässä vaiheessa käytetään yleensä automaattista optimointia. Assembler ohjelmoijat uskovat kuitenkin, että mikään kone, vaikka kuinka täydellinen, voi tehdä tämän paremmin kuin taitava ohjelmoija (kuitenkin kaikki ovat yhtä mieltä siitä, että huono ohjelmoija tekee paljon huonommin kuin tietokone).

mitä optimoida

manuaalisella koodioptimoinnilla on edessään toinen ongelma: ei tarvitse vain tietää, miten optimointi pitäisi tehdä, vaan myös se, mikä tietty osa ohjelmasta pitäisi optimoida. Eri syistä (hitaat syöttöoperaatiot, ihmisen operaattorin ja tietokoneen toimintanopeuden ero jne.) johtuen 90% ohjelman suoritusajasta käytetään vain 10% koodin suorittamiseen (tämä lausuma on melko spekulatiivinen, Pareto-periaatteen ollessa varsin kyseenalainen peruste, mutta A. Tanenbaum saa sen kuulostamaan vakuuttavalta). Koska optimointi vie ylimääräistä aikaa syrjään aikaa olet viettänyt kehittää ohjelman, sinun on parempi keskittyä optimoimalla tämä aika kriittinen 10% koodin sijaan yrittää optimoida koko ohjelman. Näitä koodinpätkiä kutsutaan pullonkauloiksi, ja ne voidaan havaita erityisillä apuohjelmilla – profiloijilla – jotka voivat mitata ohjelman eri osien suorittamiseen kuluvaa aikaa.

käytännössä optimointi tapahtuu kuitenkin yleensä “kaoottisen” ohjelmoinnin vaiheen jälkeen(mukaan lukien sellaiset menetelmät kuin “Copy-Paste”, “we’ ll see later”, “it’ s OK This way”), ja siksi se on sekoitus optimointia sellaisenaan, refaktorointia ja bugikorjauksia: yksinkertaistetaan “queer” – konstruktioita kuten strlen (path.c_str ()), loogiset ehdot kuten (A.x != 0 && a. x != 0), ja niin edelleen. Profiloijista ei ole juuri apua tällaisessa optimoinnissa. Nämä ongelmat voi kuitenkin havaita staattisilla analyysityökaluilla eli semanttisten virheiden etsimiseen tarkoitetuilla työkaluilla, jotka perustuvat lähdekoodin syväanalyysiin. Kuten näet edellä mainitusta esimerkistä outo ehto, tehoton koodi voi näkyä seurauksena virheitä (kuten painovirhe esimerkissämme, jossa.x != 0 && a. y != 0 pitäisi olla sen sijaan). Tehokas staattinen analysaattori havaitsee tällaiset koodinpätkät ja kiinnittää huomiosi niihin tuottamalla varoitusviestejä.

optimoinnin hyviä ja huonoja tuloksia

ohjelmoinnissa lähes kaikkea tulee käsitellä rationaalisuuden näkökulmasta-optimointi ei ole poikkeus. On uskomus, että kokemattoman Assembler-ohjelmoijan kirjoittama koodi on 3-5 kertaa hitaampaa kuin kääntäjän (Zubkov) tuottama koodi. Laajalti tunnettu on Knuthin lause varhaisista matalan tason optimoinneista (kuten yrityksistä säästää operaattoreita tai muuttujia): “ennenaikainen optimointi on kaiken pahan alku”.

useimmat ohjelmoijat eivät valita optimoijan tekemistä optimoinneista, joista osa on tavanomaisia ja pakollisia. Tällaisia ovat esimerkiksi pyrstökutsun optimointi funktionaalisissa kielissä (pyrstökutsu on rekursion erikoistapaus, joka voidaan esittää silmukkana).

on kuitenkin ymmärrettävä, että useat monimutkaiset optimoinnit konekoodin tasolla voivat aiheuttaa suurta kääntämisen hidastumista. Hyöty niiden avulla voit saada voi olla aivan liian merkityksetön, verrattuna yleiseen järjestelmän suunnittelun optimointeja (Wirth). On myös pidettävä mielessä, että nykykielissä kaikkine syntaktisine ja semanttisine “röyhelöineen” on monia vivahteita ja hienouksia, joten ohjelmoija, joka ei tunne niitä, voi yllättyä optimoinnin tuloksesta.

otetaan esimerkiksi C++ ja niin sanottu paluuarvon optimointi, kun Kääntäjä välttää kopioimasta funktion palauttamaa väliaikaista objektia. Koska kääntäjä jättää kopioinnin pois, tätä menetelmää kutsutaan myös “Copy elisioniksi”. Joten, seuraava koodi:

#include <iostream> struct C { C() {} C(const C&) { std::cout << "A copy was made.\n"; }}; C f() { return C();} int main() { std::cout << "Hello World!\n"; C obj = f();}

voi olla useita lähtöjä:

Hello World!A copy was made.A copy was made.Hello World!A copy was made.Hello World!

niin oudolta kuin se tuntuukin, kaikki kolme versiota ovat päteviä, koska kielistandardi sallii kopioivan rakentajan kutsujen jättämisen pois tällaisissa tapauksissa, vaikka rakentajalla olisikin sivuvaikutuksia (§12.8 Copying Class Objects, 15 kohta).

johtopäätös

näin ollen meidän tulisi aina harkita ohjelmakoodin optimointia erikoisohjelmien avulla aina kun mahdollista, mutta kuitenkin tehdä tämä hyvin huolellisesti, ja olla valmiina kääntäjän yllättävien temppujen todennäköisyyteen ajoittain.

PVS-Studio

staattisessa analysaattorissa PVS-studiossa toteutetaan diagnostiikkasarja, jonka avulla voidaan löytää tilanteita, joissa koodia voidaan optimoida. PVS-Studio kuten mikään muukaan staattinen analysaattori ei kuitenkaan voi toimia profilointityökalujen korvaajana. Vain dynaamiset ohjelmananalysaattorit pystyvät tunnistamaan pullonkaulat. Staattiset analysaattorit eivät tiedä, mitä syöttötieto-ohjelmat saavat ja kuinka usein tietty koodinpätkä suoritetaan. Siksi sanomme, että analysaattori ehdottaa joidenkin koodin “mikro-optimointien” toteuttamista, jotka eivät takaa suorituskyvyn hyötyjä.

pidetystä haitasta huolimatta PVS-Studioanalysaattori toimii hyvänä täydennyksenä profilointityökaluille. Lisäksi optimointiin liittyviä PVS-Studio-varoituksia käsiteltäessä koodi muuttuu usein yksinkertaisemmaksi ja lyhyemmäksi. Tätä vaikutusta tarkastellaan tarkemmin artikkelissa “Exploring Microoptimizations Using Tizen Code as an Example”.

Vastaa

Sähköpostiosoitettasi ei julkaista.