Programmi optimeerimine on arvutiprogrammi muutmise protsess nii, et see käivitab programmi kiiremini, tarbib vähem ressursse või töötab üldiselt kõrgema efektiivsusega. Mõned programmeerimiskeele kompilaatorid võivad optimeerimise ülesande täita automaatselt, tahtlikult optimeerimisprogrammi kasutades või käsitsi programmeerijad, kes astuvad läbi lähtekoodi ja püüavad teha konkreetseid täiustusi. Üldiselt toimub programmi optimeerimine kindlat eesmärki silmas pidades, kuna programmile saab teha väga vähe üldisi optimeerimisi, mis ei vähenda mingil moel programmi mõne muu osa optimeeritud olekut, mis tähendab, et programm suudab tavaliselt olema optimeeritud kiiruse või ressursikasutuse jaoks, kuid tavaliselt mitte mõlema jaoks. Üks tüsistusi, mis teatud tüüpi optimeerimise puhul võib tekkida, on see, et paljud kõrgetasemelised programmeerimiskeeled pakuvad nii suurt abstraktsioonitaset omakoodi ja arvutikeele vahel, et optimeerimist võib olla raske või võimatu rakendada kõikidel platvormidel igas olukorras, eriti tõlgitud keeled, mis kasutavad just-in-time (JIT) koostamist.
Programmi optimeerimise oluline kontseptsioon on idee, et optimeerimisega kaasneb tavaliselt mingi hind. Üks näide sellest on see, et kui koodiosa on optimeeritud kiiremini töötama, võib kiiruse suurenemine tulla koodi loetavuse, mälukasutuse, programmi paindlikkuse või mitmete muude kuludega. See tähendab, et programmi optimeerimine peab olema suunatud protsess, mille eesmärk on muuta programmi üks aspekt paremini toimima, olles samal ajal valmis ohverdama teiste aspektide tõhusust.
Programmi arendamise erinevates etappides saab läbi viia erinevat tüüpi programmide optimeerimist. Disaini käigus saab teha laiaulatuslikku optimeerimist, tagades, et programm näib töötavat tõhusalt. Tegeliku lähtekoodiga töötades võib optimeerimine hõlmata kõrvaliste käskude, korduvate kõnede või halvasti kirjutatud funktsioonide puudumise tagamist. Kompileerimisel teostab paljud optimeerimised automaatselt kompilaatori poolt ja programmeerija saab neid juhtida erinevate kompilaatori lülitite või juhiste abil.
Automaatne optimeerimine, nagu võib juhtuda kompilaatori või pühendunud optimeerimisprogrammiga, võib sageli hõlmata nippe, mis on liiga keerulised, et olla programmeerijate jaoks praktilised. See võib hõlmata käskude liigutamist programmis, nii et neid täidetakse algselt kirjutatud järjekorrast, kuid protsessori jaoks tõhusamal viisil. See võib hõlmata ka ressursside, näiteks mäluplokkide, tahtlikku nihutamist, et neile kiiremini juurde pääseda. Enamik programmide optimeerimisest toimub automaatselt kompilaatori tasemel.
Üks korduva või agressiivse programmi optimeerimise tüsistus on see, et kui programmi on muudetud tõhusamaks töötamiseks, muutub seda üldiselt raskemaks muuta muudel eesmärkidel, näiteks funktsioonide lisamiseks või vigade parandamiseks. See võib juhtuda siis, kui optimeerimine hakkab lukustama määratud programmi käitumist, mida ei ole lihtne muuta või uue koodiga kohandada, ilma et oleks vaja kõiki optimeerimisi tagasi võtta. Suurem probleem on see, et paljudel juhtudel muutub optimeeritud programm inimese jaoks vähem loetavaks, kuna ainult lühikeste käskude ja klassikaliste juhtimisstruktuuride asemel kasutatakse trikke ja otseteid. Nendel põhjustel on sageli programmi optimeerimise tase, mille juures on vastuvõetav peatada, kuigi drastilised koodimuudatused võivad muuta programmi veidi tõhusamaks.