Optymalizacja programu to proces modyfikacji programu komputerowego w taki sposób, aby program działał szybciej, zużywał mniej zasobów lub ogólnie działał z wyższą wydajnością. Zadanie optymalizacji może być wykonywane automatycznie przez niektóre kompilatory języka programowania, celowo za pomocą programu optymalizacyjnego, lub ręcznie przez programistów, którzy przechodzą przez kod źródłowy i próbują wprowadzić określone ulepszenia. Ogólnie rzecz biorąc, optymalizacja programu jest wykonywana z myślą o określonym celu, ponieważ istnieje bardzo niewiele ogólnych optymalizacji, które można wykonać w programie, które w żaden sposób nie zmniejszają zoptymalizowanego stanu innej części programu, co oznacza, że program zwykle może być zoptymalizowane pod kątem szybkości lub wykorzystania zasobów, ale zwykle nie obu. Jedną z komplikacji, która może wystąpić w przypadku niektórych rodzajów optymalizacji, jest to, że wiele języków programowania wysokiego poziomu zapewnia tak duży poziom abstrakcji między kodem natywnym a językiem komputerowym, że optymalizacja może być trudna lub niemożliwa do wdrożenia na wszystkich platformach we wszystkich sytuacjach, zwłaszcza w przypadku interpretowane języki, które używają kompilacji just-in-time (JIT).
Ważną koncepcją w optymalizacji programu jest idea, że optymalizacja zwykle wiąże się z pewną ceną. Jednym z przykładów jest to, że gdy fragment kodu jest zoptymalizowany do szybszego działania, wzrost szybkości może kosztować czytelność kodu, zużycie pamięci, elastyczność programu lub szereg innych kosztów. Oznacza to, że optymalizacja programu musi być procesem ukierunkowanym, mającym na celu sprawienie, aby jeden aspekt programu działał lepiej, a jednocześnie był gotów poświęcić wydajność innych aspektów.
Różne rodzaje optymalizacji programu mogą być wykonywane na różnych etapach tworzenia programu. Podczas projektowania można przeprowadzić szeroką optymalizację, upewniając się, że program wydaje się działać skutecznie. Podczas pracy z rzeczywistym kodem źródłowym optymalizacje mogą obejmować zapewnienie braku zbędnych poleceń, powtarzających się wywołań lub źle napisanych funkcji. Podczas kompilacji wiele optymalizacji jest wykonywanych automatycznie przez kompilator i programista może nimi kierować za pomocą różnych przełączników lub dyrektyw kompilatora.
Optymalizacje automatyczne, jakie mogą wystąpić w przypadku kompilatora lub programu do optymalizacji dedykacji, często mogą obejmować sztuczki, które są zbyt złożone, aby były praktyczne dla ludzkich programistów. Może to obejmować przenoszenie instrukcji w programie tak, aby były wykonywane w kolejności pierwotnie napisanej, ale w sposób bardziej wydajny dla procesora. Może również obejmować celowe przesuwanie zasobów, takich jak bloki pamięci, aby można było uzyskać do nich szybszy dostęp. Większość optymalizacji programu odbywa się automatycznie na poziomie kompilatora.
Jedną z komplikacji związanych z powtarzającą się lub agresywną optymalizacją programu jest to, że gdy program został zmodyfikowany w celu wydajniejszego działania, zwykle staje się trudniejszy do zmodyfikowania w innych celach, takich jak dodawanie funkcji lub naprawianie błędów. Może się to zdarzyć, gdy optymalizacje zaczynają blokować ustawione zachowania programu, których nie można łatwo zmienić lub dostosować do nowego kodu bez konieczności cofania wszystkich optymalizacji. Większym problemem jest to, że w wielu przypadkach zoptymalizowany program staje się mniej czytelny dla człowieka, ponieważ używa się sztuczek i skrótów zamiast tylko zwięzłych poleceń i klasycznych struktur kontrolnych. Z tych powodów często istnieje poziom optymalizacji programu, na którym można się zatrzymać, nawet jeśli drastyczne modyfikacje kodu mogą sprawić, że program będzie działał nieco wydajniej.