Optimizacija programa

U informatici, optimizacija programa ili optimizacija softvera je proces modifikacije softvera sistema kako bi se napravio pristup efikasnijeg rada ili da se koristi manje izvora.[1] Uglavnom, računarski program može biti izvršen češće, ili je u mogućnosti da radi sa manjim kapacitetom memorije ili drugih resursa, ili da vuče manju snagu.

Princip

uredi

Iako reč "optimizacija" ima isti koren kao "optimalno", retko je da proces optimizacije produkuje pravi optimalni sistem. Optimizovan sistem će uglavnom biti optimalan samo u jednoj aplikaciji ili za jednu publiku. Jedan može smanjiti količinu vremena koje je potrebno programu da izvrši neki zadatak po ceni trošenja više memorije. U aplikaciji u kojoj je prostor memorije bitan, može namerno izabrati sporiji algoritam da bi se koristilo manje memorije. Često postoji "jedan odgovara za sve" dizajn koji dobro radi u svim slučajevima, tako da inženjeri imaju kompromise da optimiziraju atribute najvećih interesa. Dodatno, napor koji se zahteva da se načini deo softvera koji je kompletno optimalan — nemouć za dalja unapređenja — je često jasniji za beneficije koje bi bile obračunate; tako da proces optimizacije može biti zaustavljen pre nego što je kompletna optimalna solucija postignuta. Srećom, često je slučaj da najveća unapređenja dolaze u ranijem procesu.

Nivoi optimizacije

uredi

Optimizacija se može javiti na više nivoa. Uglavnom najviši nivoi imaju najveći uticaj, i teško se menjaju kasnije u projektu, zahtevaju bitne promene ili kompletno ponovno pisanje ako je potrebno da budu promenjeni. Tako optimizacija se može nastaviti preko dorađivanja sa viših na niže, sa inicijalnim dodacima povećavanja i postignućem sa manje posla, i gasnije dobici postaju manji i zahtevaju više rada. Međutim, u nekim slučajevima opšti performans zavisi od performansa veoma niskih-nivoa porcija programa, i male promene pri kasnom fazom ili ranijim razmatranjem detalja niskih-nivoa može imate preterano veliki uticaj. Uglavnom neka razmatranja su data efikasno kroz projekat - iako ovo varira dosta - ali glavna optimizacija se često smatra doradom koja se mora desiti kasnije, ikada. Pri dužim projektima postoje tipična kruženja optimizacije, gde poboljšanje jedne oblasti otkriva ograničenja u drugoj, a ovi su uglavnom ograničeni kada je performans prihvatljiv ili dobici postanu premali ili preskupi. 

Pošto je performans deo specifikacije programa - program koji je mnogo spor neodgovara sviri : video igra sa 60Hz (okvira-po-sekundi) je prihvatiljiva, ali 6 fps-a je neprihvatiljivo iseckano - performans je razmatranje od starta, da se osigura da je sistem u mogućnosti da omogući određeni performans, i raniji prototipovi moraju imati grubo prihvatljiv performans da bi bilo samouverenja da će konačni sistem (sa optimizacijom) postignuti prihvatljiv performans. Ovo je ponekad izostavljeno pri verovanju da se optimizacija može uvek izvršiti kasnije, što rezultuje sistemima prototipa koji su mnogo sporiji - često po redu veličina (faktor 10h) ili više - i sistemi koji su ultimativni omašaji zato što atrhitekturalno ne mogu postići svoje ciljeve performansa, kao što je Intel 432 (1981); ili oni za koje su potrebne godine rada kako bi se postigao prihvatljiv performans, kao što je Java (1995), koja je samo postigla prihvatljiv performans sa HotSpot-om (1999). Stepen pri kome se performans menja između prototipa i produkcionog sistema, i kako je podložan za optimizaciju, može biti značajan izvor nesigurnosti i rizika. 

  • Nivo dizajna

Pri najvećem nivou, dizajn može biti optimizovan da najbolje koristi dostupne resurse, date ciljeve, ograničenja, i neočekivana korišćenja/opterećenja. Arhitektualni dizajn sistema u najvećoj meri utiče na njegov performans. Na primer, sistem kod koga je mreža ograničena kašnjenjem (gde je kašnjenje mreže glavno ograničenje pri opštem performansu) bi bila optimizovana da smanji putovanja mreže, idealno praveći jedan zahtev (ili nijedan zahtev, kao u puš protokolu) radije nego više kružnih putovanja. Izbor dizajna zavisi od ciljeva: kada se dizajnira kompilator, ako je brza kompilacija ključ prioriteta, kompilator jednog-prolaza je brži od kompilatora sa više-prolaza (pretpostavljajući isti posao), ali ako je brzina izlazećeg koda cilj, sporiji kompilator sa više-prolaza odgovara cilju bolje, iako mu treba duže vremena. Izbor platforme i programskog jezika se javlja pri ovom nivou, i njihovo često menjanje zahteva potpuno ponovno pisanje, iako modularni sistem može dozvoliti samo ponovno pisanje neke komponente - na primer, Pajtonov program može ponovo napisati sekcije kritičnog-performansa u S-u.  U distribuiranom sistemu, izbor arhitekture (klient-server, vršnjak-do-vršnjaka, itd.) se javlja pri nivou dizajna, i može biti težak za menjanje, posebno ako se sve komponente ne mogu promeniti u sinhronizaciji (npr., stari klijenti).

  • Algoritmi i strukture podataka

Imajući u vidu ukupan dizajn, dobar izbor efikasnih algoritama i struktura podataka, i efikasnih implementacija tih algoritama i struktura podataka dolazi sledeće. Posle dizajna, izbor algoritama i struktura podataka utiče na efikasnost više nego bilo koji aspekt programa. Uglavnom strukture podataka su teže za menjanje nego algoritmi, pošto pretpostavka strukture podataka i njene pretpostavke performansa se koriste kroz program, iako ovo može biti umanjeno korišćenjem apstraktnog tipa podataka u definicijama funkcije, i zadržava konkretne definicije strukture podataka ograničene za nekoliko mesta. 

Za algoritme, ovo primarno postoji za osiguravanje da su algoritmi konstantni O (log n), linearni O (n), ili u nekim slučajevima log-linearni O (n log n) pri unosu (i u vremenu i u prostoru). Algoritmi sa kvadratnom kompleksnošću O(n2) ne uspevaju da se izmere, i čak linearni algoritmi prouzrokuju probleme ako se pozivaju više puta, i uglavnom su zamenjeni konstantama ili logaritmima ako je moguće.

Osim asimptotskog reda rasta, pitanje konstantnih faktora: asimptotski sporiji algoritam može biti brži ili manji (jer je jednostavniji) od asimptotski bržeg algoritma kada su oboje okrenuti ga manjem ulazu, što može biti slučaj koji se javlja u realnosti. Često će hibridni algoritam pružiti najbolji performans, prilikom ove razmene veličine.

Generalna tehnika za poboljšanje performansa je da se izbegne posao. Dobar primer je korišćenje brzog puta za česte slučajeve, što poboljšava performans izbegavajući nepotrebni posao. Na primer, korišćenjem jednostavnog rasporeda teksta algoritma za tekst na Latinici, samo menjanje na kompleksni raspored algoritma za kompleksne skripte, kao što je Davangari. Još jedna važna tehnika je kešovanje, delimična memorizacija, što izbegava suvišne komputacije. Zbog važnosti hvatanja, postoje često mnogi nivoi kešovanja u sistemu, što može prouzrokovati probleme korišćenja memorije, i tačnost problema od ostataka keša. 

  • Nivo izvornog koda

Osim generalnih algoritama i njihovih implementacija nad apstraktnom mašinom, konkretni izbori nivoa izvornog koda može učiniti bitnu razliku. Na primer, na ranijim S-ovim kompilatorima, while(1) je bio sporiji od for(;;) za bezuslovnu petlju, zato što je while(1) procenjen sa 1 i onda je imao uslovni skok koji je testiran ako je tačan, dok jefor (;;) imao bezuslovni skok . Neke optimizacije (kao što je ova) se mogu danas izvršiti preko optimizacije kompilatora. Ovo zavisi od jezika izvora, ciljanog mašinskog jezika, i od kompilatora, i može biti težak za razumevanje ili za prognoziranje i menja se tokom vremena; ovo ključ mesta gde je razumevanje kompilatora i mašinskog koda može poboljšati performans. Petlja-invarijanta kretanje koda i povratna vrednosti optimizacije su primeri optimizacije koji smanjuju potrebu za pomoćne promenljive i može čak rezultovati bržim performansom izbegavajući kružnu optimizaciju. 

  • Nivo građenja

Između izvora i nivoa kompilacije, direktive i zastave građenja se mogu koristiti da upotpuni performans opcija u izvornom kodu i kompilatoru respektivno, kao što se korišćenje preprocesora definiše da bi se uklonile bezpotrebne karakteristike softvera, optimizovanje za specifične modele softvera ili mogućnosti hardvera, ili predviđanje granjanja, na primer. Softver baziran na izvoru distribucionog sistema kao što je BSD Port i Džentu Portage može iskoristiti prednost ove forme optimizacije. 

  • Nivo kompiliranja

Korišćenjem optimizacije kompilatora se teži da se osigura da izvršni modul bude optimizovan barem toliko koliko može kompilator predvideti.

  • Asembl nivo

Pri najnižem nivou, pisanje koda koristeći asembl jezikom, dizajniranog za određenu platformu hardvera može proizvesti najefikasniji kompaktni kod ako programer iskoristi prednosti punog repertoara mašinskih instrukcija. Mnogi operativni sistemi korišćeni kod ugrađenih sistema su tradicionalno ispisani u asembler kodu iz ovog razloga. Programi (drugi od veoma malih programa) su retko ispisani iz početka da završe u asembleru prilikom koga su vreme i cena uključeni. Mnogi su kompilirani od jezika visokog nivoa do asemblera i ručno optimizovani odatle. Kada su efikasnost i veličina manje važni veliki delovi mogu biti ispisani u jeziku visokog-nivoa.

Sa modernijim optimizacijama kompilatora i većom kompleksnošću novijih procesora, teže je napisati efikasniji kod od onoga što kompilator generiše, i nekoliko projekata imaju potrebu za "ultimativnim" korakom optimizacije.

Mnogi ispisani kodovi danas imaju nameru da rade na što više mašina što je moguće. Kao posledica, programeri i kompilatori ne koriste uvek prednost efikasnijih instrukcija koji su pruženi od strane novijih procesora ili nepreciznosti starijih modela. Kao dodatak, podešeni asembler kod za određeni procesor bez korišćenja takvih instrukcija može idalje biti podoptimalan na različitom procesoru, očekuje je različito podešavanje koda.

Danas će radije nego da pišu u asembler jeziku, programeri koristiti disasembler kako bi analizirali izlaz kompilatora i promenili visok-nivo izvornog koda tako da bi mogao biti kompajliran efikasnije, ili da bi se shvatilo zašto nije efikasan .

  • Vreme rada

U-pravom-trenutku kompilatori mogu proizvesti proizvoljni mašinski kod baziran na rantajm podacima, po ceni glave. Ovo tehnika datira od ranijih motora regularnih izlaza, i postala je široko korišćena preko Java HotSpota i V8 za Javaskriptu. U nekim slučajevima adaptivna optimizacija može izvršiti rantajm optimizaciju produžavajući mogućnost statičnih kompilatora podešavajući dinamično parametre prema pravom unosu ili ostalim faktorima. 

Profilno-vođena optimizacija je ispred-vremena (AOT) kompilacija optimizacije tehnika baziranih na rantajm profilima, i slično je statičnim "prosečnim slučajevima" analogno dinamičnoj tehnici adaptivne optimizacije.

Samo-modifikujući kod može izmeniti sam sebe u odgovoru na rantajm uslove da bi se optimizovao kod; ovo je najčešće u asemblerovim jezicima programa.

Neki dizajni procesora mogu izvršiti neke optimizacije pri rantajmu. Vandredno izvršenje, spekulativno izvršenje, instrukcioni cevovodi, i predviđanje grananja. Kompilatori mogu da pomognu programu da uzme korist ovih karakteristika procesora, na primer kroz raspored instrukcija.

Zavisnost platforme i nezavisne optimizacije

uredi

Optimizacija koda može takođe biti široko kategorizovana kao zavisna-platforma i tehnike nezavisne-platforme. Dok su kasniji efektniji kod veći ili kod svih platformi, tehnike zavisne-platforme koriste specifične karakteristike jedne platforme, ili se oslanjaju na parametre u zavisnosti od jedne platforme ili od jednog procesora. Pisanje ili proizvodnja različitih verzija istog koda za različite procesore može biti potrebno. Na primer, u slučaju kompiliranje-nivoa optimizacije, tehnike nezavisne-platforme su generičke tehnike (kao što je odmotavanje petlje, redukcija pri pozivima funckije, rutine efikasnosti memorije, redukcija uslova, itd.), koji utiču na većinu arhitektura procesora na sličan način. Uglavnom, ovo služi da smanji totalnu dužinu puta instrukcije koja se zahteva za upotpunjavanje programa i/ili da smanju ukupno korišćenje memorije tokom procesa. Sa druge strane, tehnike zavisne-platforme uključuju raspored instrukcije, instrukcija-nivo paralelizam, podatak-nivo paralelizam, tehnike optimizacije keša (tj., parametri koji se razlikuju pri različitim platformama) i optimalni raspored instrukcije može biti drugačiji čak i na različitim procesorima iste arhitekture.

Smanjivanje snage

uredi

Računarski zadaci mogu biti izvršeni na nekoliko različitih način sa varirajućom efikasnošću. Efikasnija verzija sa istom funkcionalnošću je poznata kao smanjivanje snage. Na primer, razmotriti sledeći S kod pregledati čija je namera da dobije sumu svih celih brojeva od 1 do N:

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

Ovaj kod može (pretpostavljajući da nema aritmetičkog prelivanja) se ponovo napisati koristeći matematičku formulu kao što je :

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

Optimizacija, ponekad izvršena automatski preko optimizovanog kompilatora, je da selektuje metod (algoritam) koji je više komputaciono efikasniji, dok zadržava istu funkcionalnost. Videti algoritamsku efikasnost za diskusiju za neke od ovih tehnika. Međutim, značajno poboljšanje u performansu se može često postići sklanjanjem tuđe funckionalnosti.

Optimizacija nije uvek očigledan ili intuitivan proces. U primeru iznad, "optimizovana" verzija može u stvari biti sporija nego originalna verzija ako je N veoma malo i desi se da određeni hardver bude mnogo brži pri izvršenju adicije u operacija petljanja nego množenje i deljenje.

Kompromisi

uredi

U nekim slučajevima, međutim, optimizacija se oslanja na korišćenju razrađenih algoritama, korišćenje "specijalnih slučajeva" i specijalnih "trikova" i izvršavanje kompleksnih kompromisa. "Potpuno optimizovan" program može biti teži za razumevanje i otuda može imati više grešaka nego neoptimizovane verzije. Osim eliminacije očiglednih antišablona, neki bivo kod optimizacija  smanjuje sposobnost snabdevanja.

Optimizacija će se uglavnom fokusirati na poboljšanje samo jednog ili dva aspekta performansa: vreme izvršenja, korišćenje memorije, prostor na disku, protok, konzumiranje snage ili neki drugi resurs. Ovo će uglavnom zahtevati kompromis — gde je jedan faktor optimizovan po cenu drugih. Na primer, povećanjem veličine keša poboljšava rantajm performans, ali takođe povećava konzumiranje memorije. Ostali česti kompromisi ukljuluju jasnoću koda i konciznost.

Postoje instance gde programer koji izvršava optimizaciju mora odlučiti da načini softver boljim za neke operacije ali po cenu toga da čini ostale operacije manje efikasnijim. Ovi kompromisi mogu ponekad biti ne-tehničke prirode  — kao kada konkurent objavi benčmark rezultat koji mora biti pobeđen kako bi se poboljšao komercijalni uspeh ali možda dolazi sa teretom da čini normalno korišćenje softvera manje efikasnim. Takve promene se ponekad na šalu naivaju pesimizacije.

Uska grla

uredi

Optimizacija  može uključivati pronalaženje uskog grla u sistemu - komponente koja je ograničava faktor performansa. U zahtevima koda, ovo će često biti vruća tačka - kritični deo koda koji je primarni potrošač potrebno resursa - iako može da bude drugi faktor, kao što je I/O kašnjenje ili mrežni protok.

U računarskoj nauci, potrošnja resursa obično prati formu jakog zakona distribucije, i Pareto princip može biti primenjen na optimizaciju resursa posmatranjem da je 80% resursa tipično korišćeno od strane 20% operacija.[2] U softverskom inženjerstvu, često je bolja aproksimacija da 90% vremena izvršenja računarskog programa je potrošeno na izvršenje 10% koda (poznato kao 90/10 zakon u ovom kontekstu).

Kompleksniji algoritmi i strukture podataka rade dobro sa mnogim stavkama, dok su jednostavni algoritmi pogodniji za manje količine podataka — podešavanje, vreme instalacije, i konstantni faktori kompleksnijeg algoritma mogu prevagnuti korist, i tako hibridni algoritam ili adaptivni algoritam može biti brži od jednog algoritma.

U nekim slučajevima, dodavanje više memorije može pomoći programu da radi brže. Na primer, filtriran program će često čitati svaku liniju i filter i izbaciće tu liniju odmah. Ovo samo koristi dovoljno memorije za jednu liniju, ali performans je tipično siromašan, zbog gašnjenja svakog čitanja diska. Performans može biti dosta poboljšan čitanjem čitavog fajla nego pisanjem filtriranog rezultata, iako ovo koristi mnogo više memorije. Kešovanje rezultata je slično efektivan, iako takođe zahteva veće korišćenje memorije.

Kada da se optimizuje

uredi

Optimizacija može smanjiti čitkost i da doda kod koji je korišćen samo kako bi se poboljšao performans. Ovo može zakomplikovati programe ili sisteme, čineći ih težim za održavanje i debagovanje. Kao rezultat, optimizacija ili performans podešavanja je često izvršena pri kraju razvojnog stadijuma.

Donald Knut je sačinio sledeće dve izlave za optimizaciju:

"Trebalo bi da zaboravimo o malim efikasnostima, recimo oko 97% vremena: preuranjena optimizacija je koren svog zla. I dalje bi trebalo da propuštamo naše prilike u kritičnih 3%"[3]

(Takođe je pripisao izvaju Toniju Horu nekoliko godina kasnije,[4] iako ovo može biti greška kako Hor trvdi pošto je skovao frazu.[5])

"U utvrđenom inženjeringu discimplinuje se 12% poboljšanja, lako postignutih, nikada nije smatran marginalno i ja verujem da isto gledište treba da prevlada u softverskom inženjerstvu"[3]

"Preuranjena optimizacija" je fraza korišćena da se opiše situacija gde programer dopušta razmatranjima performansa da utiču na dizajn dela koda. Ovo može da rezultuje dizajnu koji nije čist kao što bi mogao da bude ili kod koji nije tačan, zato što je kod komplikovan zbog optimizacije i programeru je odvučena pažnja optimizacijom.

Kada se odlučuje da li da se optimizuje deo programa, Amdalov zakon treba uvek da se ima na umu: uticaj na celokupni program zavisi dosta od toga koliko je vremena ustavari potrošeno pri specifičnom delu, što nije uvek jasno gledanjem koda bez analize performansa.

Bolji pristup je dakle prvo dizajn, kod iz dizajna i onda profil/benčmark rezultujući kod kako bi se videlo koji delovi bi trebalo da se optimizuju. Jednostavan i elegantan dizajen je često lakši za optimizovanje pri ovom stadijumu, i profilisanje može otkriti nenadane probleme performansa koje ne bi bile adresirane od strane preuranjene uptimizacije.

U praksi, često je neophodno zadržati ciljeve performansa na umu kada se prvo dizajnira softver, ali programer balancira ciljeve dizajna i optimizacije.ž

Makroi

uredi

Optimizacija tokom razvoja koda koristeći makroe uzima različite forme u različitim jezicima.

Kod nekih proceduralnih jezika, kao što je S i S++, makroi su implementovani korišćenjem znakovne supstitucije. Danas, inlajn funkcije mogu biti korišćene kao alternativa sigurnih tipova u mnogim slučajevima. U oba slučaja, telo inlajn funkcije može proći dalje kompilirano-vreme optimizacija od strane kompilatora, uključujući konstantno savijanje, koje može pomeriti proračune pri kompiliranom vremenu.

U mnogim jezicima funkcionalnog programiranja makroi su implementovani korišćenjem supstitucija raščlanjenog-vremena raščlanjenih stabala/apstraktnih sintaksa stabala, što kako se tvrdi ih čini sigurnijim za korišćenje. Pošto je u mnogim slučajevima interpretacija korišćenja, to je jedan način da se osiguraju takvi proračuni koji se samo izvršavaju pri raščlanjenom-vremenu, i ponekad jedini način.

Lisp je izmislio ovaj stil za makro, i takvi makroi se često nazivaju "makroi kao-Lisp". Sličan efekat se može postići korišćenjem šablonskog metaprogramiranja u S++-u.

U oba slučaja, posao je premešten na kompilirano-vreme. Razlika između S makroa na jednoj strani, i Lisp-ovih makroa i S++ šablonskog metaprogramiranja na drugoj strani, jeste taj da kasnije alatke dozvoljavaju izvršavanje algebarskih izračunavanja pri kompiliranom-vremenu/raščlanjenom-vremenu, dok S ekspanzija makroa ne radi nikakva izračunavanja, i oslanja se mogućnost optimizera da to izvrši. Dodatno, S makroi ne podržavaju direktno rekurziju ili iteraciju, tako da nisu Tjuring potpuni.

Kao i sa bilo kojom optimizacijom, međutim, često je teško predvideti gde će takve alatke imati najveći uticaj pre nego što je projekat završen.

Automatizovana i ručna optimizacija

uredi

Vidi još Kategorija: Kompilatroske optimizacije

Optimizacija može biti automatizovana preko kompilatora ili izvršena preko programera. Dobici su uglavnom ograničeni za lokalnu optimizaciju, i veći za globalne optimizacije. Obično, najjala optimizacije je nači superioran algoritam.

Optimizovanje celog sistem je obično preduzet od strane programera zato što je previše kompleksno za automatizovane optimizere. U ovoj situaciji, programeri ili sistemski administratori eksplicitno menjaju kod tako da opšti sistem radi bolje. Iako može proizvesti bolju efikasnost, daleko je skuplji nego automatizovane optimizacije.

Koristiti profilera (ili analizatora performansa) kako bi se pronašle sekcije programa koji uzimaju najviše resursa —usko grlo. Programeri ponekad veruju da imaju ideju šta je usko grlo, ali intuicija je u dosta slučajeva netačna. Optimizovanje nebitnog dela koda će često malo uraditi da bi se pomoglo oko opšteg performansa.

Kada je usko grlo lokalizovano, optimizacija obično počinje sa promišljanjem algoritma koji je korišćen u programu. Češće da nego ne, određeni algoritam može biti posebno prilagođen za određeni problem, popuštanje boljeg performansa nego generički algoritam. Na primer, zadatak sortiranja velike liste stavke je često izvršena sa kviksort rutinom, koja je jedna od najefikasnijih generičnih algoritama. Ali ako je neka karakteristika stavki iskoristiva (na primer, već su uređeni u nekom određenom redu), druga metoda se može koristiti, ili čak proizvoljno-sačinjena rutira sortiranja. 

Kasnije kada je programer sa razlogom siguran da je najbolji algoritam selektovan, optimizacija kod može da počne. Petlje se mogu odviti (za niže petlje, iako ovo često može dovesti do niže brzine ako preoptereti keš procesora), tipove podataka što je manje moguće za korišćenje, celobrojni račun se može koristiti umesto decimalne-tačke, i tako dalje.(Videti algoritamsku efikasnost artikal za ovo i ostale tehnike.)

Uska grla performansa se mogu javiti zbog ograničenja jezika pre nego kod algoritama ili struktura podataka korišćenih u programu. Ponekad, kritični deo programa može biti ponovo ispisan u drugom programskom jeziku koji daje direktniji pristup osnovnoj mašini. Na primer, često je za veoma visokog-nivoa jezike kao što je Pajton da ima ispisane module u S-u za veću brzinu. Programi koji su veći ispisanu u S-u mogu imati module ispisane u asembleru. Programi ispisani u D-u mogu koristiti inlajn asembler.

Ponovno pisanje sekcija "isplaćuje se" u ovim uslovima zbog generalnog "pravila palca" poznatog kao 90/10 zakon, koji kaže da 90% vremena potrošenog u 10% koda, i samo 10% vremena u ostalih 90% koda. Tako da, ulaganje intelektualnog napora u optimizovanje samo malog dela programa može imati veliki utacija na opštu brzinu — ako tačni delovi mogu biti locirani.

Manualna optimizacija ponekad ima kontra efekat narušavajući čitkost. Tako da optimizacije koda treba da budu oprezno dokumentovane (preporučeno koristeći komentare), i njihov efekat treba biti u budućem razvoju procenjen.

Program koji izvršava automatizovanu optimizaciju se naziva optimizer. Većina optimizera su ubačeni u kompilatore i rade tokom kompilacije. Optimizeri mogu često krojiti generalisani kod za specifične procesore.

Danas, automatizovane optimizacije su skoro ekskluzivno ograničene na optimizaciju kompilatora. Međutim, zato što su kompilatorske optimizacije obično ograničene na fiksiranu grupu radije generalnih optimizacija, postoji razmatrajući zahtev za optimizere koji može prihvatiti opise problema i jezički-specifične optimizacije, dozvoljavajući inženjeru da specifira proizvoljne optimizacije. Alatke koje prihvataju opise optimizacija se nazivaju programske transformacije sistema i počinju da se primenjuju na prave sisteme softvera kao što je S++.T

Neki jezici visokog nivoa (Ajfel, Esterel) optimiziraju programe koristeći međujezik.

Mrežno računanje ili raspodeljeno izračunavanje ima cilj da optimizira ceo sistem, pomerajući zadatke sa račinara sa visokim korišćenjem na računare sa idle vremenom.

Potrebno vreme za optimizaciju

uredi

Ponekad, vreme potrebno da se preduzme optimizacija u tome sama od sebe može predstavljati problem.

Optimizacija postojećeg koda obično ne dodaje nove karakteristike, i još gore, može dodati nove bagove u prethodnom kodu (kao što bi bilo koja promena mogla). Zato što ručno optimiziranu kod može neki put imati slabiju "čitkost" od neoptimizovanog koda, optimizacija može uticati na pogodnost održavanja takođe. Optimizacija dolazi po sa cenom i važno je biti sugran da je investicija vredna.

Automatski optimizer (ili optimizacija kompilatora, program koji izvršava optimizaciju koda) mora sam od sebe da bude optimizovan, ili da dalje poboljša efikasnost ciljanih programa ili da ubrza sopstvenu operaciju. Kompilacija izvršena sa optimizacijom "uključena" obično traje duže, iako je ovo jedini problem kada su programi prilično veliki.

Posebno, za u-pravom-trenutku kompilatore performans rantajm kompajl komponente, izvršava se zajedno sa ciljanim kodom, je ključ za povoljšavanje opšte brzine izvršenja.

Citati

uredi
  • "Redosled po kome će operacije biti izvršene u svakom mogućem slučaju je veoma interesantno i zanimljivo pitanje, na koje nam naš prostor ne dozvoljava u potpunosti da uđemo. Pri skoro svakom izračunavanju velika raznolikost aranžmana za uspeh procesa je moguć, i različita razmatranja moraju uticati na selekciju među njima za svrhe Računskog Motora. Jedan bitni objekt je da se izabere aranžman koji će imati tendenciju da smanji na minimum potrebno vreme za završetak izračunavanja." — Beleške Ejde King o analitičkom motoru 1842.
  • "Još greha izračunavanja su počinjeni zarad efikasnosti (bez neophodne želje za uspehom) nego za bilo koji drugi razlog — uključujući slepu glupost." — Vilijam Vulf.
  • "Treblo bi da zaboravimo na male efikasnosti, recimo oko 97% vremena: preuranjene optimizacije su koren zlog. Ipak ne bi trebalo da propustimo prilike u onih kritičnih 3%. Dobar programer neće biti uvučen u samoljublje preko takve logike, biće pameta da pogleda pažljivo na kritičan kod; ali samo kada se kod identifikuje"[6] — Donald Knut
  • "Uska grla se javljaju u iznenađujućim mestima, tako da ne pokušavajte da pogodite iz drugog puta i ubacite hak brzine dok ne dokažete gde se usko grlo nalazi." — Rob Pike
  • "Prvo Pravilo Programske Optimizacije: Ne radi to. Drugo Pravilo Programske Optimizacije (samo za eksperte): Ne radi to još." —Majkl A. Džekson

Reference

uredi
  1. ^ Robert Sedgewick, Algorithms, (1984). str. 84
  2. ^ Wescott 2013.
  3. ^ a b Knuth, Donald (December 1974).
  4. ^ The Errors of Tex, in Software—Practice & Experience, Volume 19, Issue 7 (July 1989). str. 607–685, reprinted in his book Literate Programming (p. 276)
  5. ^ Tony Hoare, a 2004 email
  6. ^ Knuth, Donald: Structured Programming with Goto Statements.

Literatura

uredi

Spoljašnje veze

uredi