У информатици, оптимизација програма или оптимизација софтвера је процес модификације софтвера система како би се направио приступ ефикаснијег рада или да се користи мање извора.Robert Sedgewick, Algorithms, (1984). стр. 84 Углавном, рачунарски програм може бити извршен чешће, или је у могућности да ради са мањим капацитетом меморије или других ресурса, или да вуче мању снагу.

Принцип Иако реч "оптимизација" има исти корен као "оптимално", ретко је да процес оптимизације продукује прави оптимални систем. Оптимизован систем ће углавном бити оптималан само у једној апликацији или за једну публику. Један може смањити количину времена које је потребно програму да изврши неки задатак по цени трошења више меморије. У апликацији у којој је простор меморије битан, може намерно изабрати спорији алгоритам да би се користило мање меморије. Често постоји "један одговара за све" дизајн који добро ради у свим случајевима, тако да инжењери имају компромисе да оптимизирају атрибуте највећих интереса. Додатно, напор који се захтева да се начини део софтвера који је комплетно оптималан — немоућ за даља унапређења — је често јаснији за бенефиције које би биле обрачунате; тако да процес оптимизације може бити заустављен пре него што је комплетна оптимална солуција постигнута. Срећом, често је случај да највећа унапређења долазе у ранијем процесу.

Нивои оптимизације Оптимизација се може јавити на више нивоа. Углавном највиши нивои имају највећи утицај, и тешко се мењају касније у пројекту, захтевају битне промене или комплетно поновно писање ако је потребно да буду промењени. Тако оптимизација се може наставити преко дорађивања са виших на ниже, са иницијалним додацима повећавања и постигнућем са мање посла, и гасније добици постају мањи и захтевају више рада. Међутим, у неким случајевима општи перформанс зависи од перформанса веома ниских-нивоа порција програма, и мале промене при касном фазом или ранијим разматрањем детаља ниских-нивоа може имате претерано велики утицај. Углавном нека разматрања су дата ефикасно кроз пројекат - иако ово варира доста - али главна оптимизација се често сматра дорадом која се мора десити касније, икада. При дужим пројектима постоје типична кружења оптимизације, где побољшање једне области открива ограничења у другој, а ови су углавном ограничени када је перформанс прихватљив или добици постану премали или прескупи. 

Пошто је перформанс део спецификације програма - програм који је много спор неодговара свири : видео игра са 60Hz (оквира-по-секунди) је прихватиљива, али 6 fps-а је неприхватиљиво исецкано - перформанс је разматрање од старта, да се осигура да је систем у могућности да омогући одређени перформанс, и ранији прототипови морају имати грубо прихватљив перформанс да би било самоуверења да ће коначни систем (са оптимизацијом) постигнути прихватљив перформанс. Ово је понекад изостављено при веровању да се оптимизација може увек извршити касније, што резултује системима прототипа који су много спорији - често по реду величина (фактор 10х) или више - и системи који су ултимативни омашаји зато што атрхитектурално не могу постићи своје циљеве перформанса, као што је Intel 432 (1981); или они за које су потребне године рада како би се постигао прихватљив перформанс, као што је Јава (1995), која је само постигла прихватљив перформанс са HotSpot-ом (1999). Степен при коме се перформанс мења између прототипа и продукционог система, и како је подложан за оптимизацију, може бити значајан извор несигурности и ризика.  Ниво дизајна При највећем нивоу, дизајн може бити оптимизован да најбоље користи доступне ресурсе, дате циљеве, ограничења, и неочекивана коришћења/оптерећења. Архитектуални дизајн система у највећој мери утиче на његов перформанс. На пример, систем код кога је мрежа ограничена кашњењем (где је кашњење мреже главно ограничење при општем перформансу) би била оптимизована да смањи путовања мреже, идеално правећи један захтев (или ниједан захтев, као у пуш протоколу) радије него више кружних путовања. Избор дизајна зависи од циљева: када се дизајнира компилатор, ако је брза компилација кључ приоритета, компилатор једног-пролаза је бржи од компилатора са више-пролаза (претпостављајући исти посао), али ако је брзина излазећег кода циљ, спорији компилатор са више-пролаза одговара циљу боље, иако му треба дуже времена. Избор платформе и програмског језика се јавља при овом нивоу, и њихово често мењање захтева потпуно поновно писање, иако модуларни систем може дозволити само поновно писање неке компоненте - на пример, Пајтонов програм може поново написати секције критичног-перформанса у С-у.  У дистрибуираном систему, избор архитектуре (клиент-сервер, вршњак-до-вршњака, итд.) се јавља при нивоу дизајна, и може бити тежак за мењање, посебно ако се све компоненте не могу променити у синхронизацији (нпр., стари клијенти). Алгоритми и структуре података Имајући у виду укупан дизајн, добар избор ефикасних алгоритама и структура података, и ефикасних имплементација тих алгоритама и структура података долази следеће. После дизајна, избор алгоритама и структура података утиче на ефикасност више него било који аспект програма. Углавном структуре података су теже за мењање него алгоритми, пошто претпоставка структуре података и њене претпоставке перформанса се користе кроз програм, иако ово може бити умањено коришћењем апстрактног типа података у дефиницијама функције, и задржава конкретне дефиниције структуре података ограничене за неколико места. 

За алгоритме, ово примарно постоји за осигуравање да су алгоритми константни О (log n), линеарни О (n), или у неким случајевима log-линеарни О (n log n) при уносу (и у времену и у простору). Алгоритми са квадратном комплексношћу О(n2) не успевају да се измере, и чак линеарни алгоритми проузрокују проблеме ако се позивају више пута, и углавном су замењени константама или логаритмима ако је могуће.

Осим асимптотског реда раста, питање константних фактора: асимптотски спорији алгоритам може бити бржи или мањи (јер је једноставнији) од асимптотски бржег алгоритма када су обоје окренути га мањем улазу, што може бити случај који се јавља у реалности. Често ће хибридни алгоритам пружити најбољи перформанс, приликом ове размене величине.

Генерална техника за побољшање перформанса је да се избегне посао. Добар пример је коришћење брзог пута за честе случајеве, што побољшава перформанс избегавајући непотребни посао. На пример, коришћењем једноставног распореда текста алгоритма за текст на Латиници, само мењање на комплексни распоред алгоритма за комплексне скрипте, као што је Давангари. Још једна важна техника је кешовање, делимична меморизација, што избегава сувишне компутације. Због важности хватања, постоје често многи нивои кешовања у систему, што може проузроковати проблеме коришћења меморије, и тачност проблема од остатака кеша.  Ниво изворног кода Осим генералних алгоритама и њихових имплементација над апстрактном машином, конкретни избори нивоа изворног кода може учинити битну разлику. На пример, на ранијим С-овим компилаторима, while(1) је био спорији од for(;;) за безусловну петљу, зато што је while(1) процењен са 1 и онда је имао условни скок који је тестиран ако је тачан, док јеfor (;;) имао безусловни скок . Неке оптимизације (као што је ова) се могу данас извршити преко оптимизације компилатора. Ово зависи од језика извора, циљаног машинског језика, и од компилатора, и може бити тежак за разумевање или за прогнозирање и мења се током времена; ово кључ места где је разумевање компилатора и машинског кода може побољшати перформанс. Петља-инваријанта кретање кода и повратна вредности оптимизације су примери оптимизације који смањују потребу за помоћне променљиве и може чак резултовати бржим перформансом избегавајући кружну оптимизацију.  Ниво грађења Између извора и нивоа компилације, директиве и заставе грађења се могу користити да употпуни перформанс опција у изворном коду и компилатору респективно, као што се коришћење препроцесора дефинише да би се уклониле безпотребне карактеристике софтвера, оптимизовање за специфичне моделе софтвера или могућности хардвера, или предвиђање грањања, на пример. Софтвер базиран на извору дистрибуционог система као што је BSD Port и Џенту Portage може искористити предност ове форме оптимизације.  Ниво компилирања Коришћењем оптимизације компилатора се тежи да се осигура да извршни модул буде оптимизован барем толико колико може компилатор предвидети. Асембл ниво При најнижем нивоу, писање кода користећи асембл језиком, дизајнираног за одређену платформу хардвера може произвести најефикаснији компактни код ако програмер искористи предности пуног репертоара машинских инструкција. Многи оперативни системи коришћени код уграђених система су традиционално исписани у асемблер коду из овог разлога. Програми (други од веома малих програма) су ретко исписани из почетка да заврше у асемблеру приликом кога су време и цена укључени. Многи су компилирани од језика високог нивоа до асемблера и ручно оптимизовани одатле. Када су ефикасност и величина мање важни велики делови могу бити исписани у језику високог-нивоа.

Са модернијим оптимизацијама компилатора и већом комплексношћу новијих процесора, теже је написати ефикаснији код од онога што компилатор генерише, и неколико пројеката имају потребу за "ултимативним" кораком оптимизације.

Многи исписани кодови данас имају намеру да раде на што више машина што је могуће. Као последица, програмери и компилатори не користе увек предност ефикаснијих инструкција који су пружени од стране новијих процесора или непрецизности старијих модела. Као додатак, подешени асемблер код за одређени процесор без коришћења таквих инструкција може идаље бити подоптималан на различитом процесору, очекује је различито подешавање кода.

Данас ће радије него да пишу у асемблер језику, програмери користити дисасемблер како би анализирали излаз компилатора и променили висок-ниво изворног кода тако да би могао бити компајлиран ефикасније, или да би се схватило зашто није ефикасан . Време рада У-правом-тренутку компилатори могу произвести произвољни машински код базиран на рантајм подацима, по цени главе. Ово техника датира од ранијих мотора регуларних излаза, и постала је широко коришћена преко Јава ХотСпота и В8 за Јаваскрипту. У неким случајевима адаптивна оптимизација може извршити рантајм оптимизацију продужавајући могућност статичних компилатора подешавајући динамично параметре према правом уносу или осталим факторима. 

Профилно-вођена оптимизација је испред-времена (AOT) компилација оптимизације техника базираних на рантајм профилима, и слично је статичним "просечним случајевима" аналогно динамичној техници адаптивне оптимизације.

Само-модификујући код може изменити сам себе у одговору на рантајм услове да би се оптимизовао код; ово је најчешће у асемблеровим језицима програма.

Неки дизајни процесора могу извршити неке оптимизације при рантајму. Вандредно извршење, спекулативно извршење, инструкциони цевоводи, и предвиђање гранања. Компилатори могу да помогну програму да узме корист ових карактеристика процесора, на пример кроз распоред инструкција.

Зависност платформе и независне оптимизације