Często powtarzanym bon motem jest twierdzenie, iż przedwczesna optymalizacja (preemptive optimization) jest źródłem wszelkiego zła. Dużo w tym racji i równie dużo przesady. Jednak na pewno faktem jest, że pisanie wydajnych i efektywnych, czyli zoptymalizowanych (“przedwcześnie” lub poniewczasie) programów nie jest prostym zadaniem.
W celu łatwiejszej identyfikacji obszarów, w których można zastosować polepszające wydajność poprawki, możliwe rodzaje optymalizacji zwykle dzieli się na kilka rodzajów. Niektóre z nich są aplikowane przez kompilator i pozostają w dużym stopniu poza kontrolą programisty, który może co najwyżej unikać sytuacji blokujących możliwość ich zastosowania – jeśli w ogóle o nich wie. Pozostałe można pewnie zaklasyfikować na kilka sposobów, a podziałem stosowanym przeze mnie jest następujący:
Kolejność na powyższej liście odpowiada głównie zakresowi, w jaki optymalizacje wpływają na kształt programu i jego kod. Dość powszechna jest aczkolwiek opinia, że zmiany o bardziej dalekosiężnych skutkach dają też wyraźniejsze efekty, co generalnie nie musi być prawdą. Wystarczy przypomnieć sobie znaną zasadę Pareto, która w tym przypadku oznacza, że 10/20% jest wykonywana przez 90/80% czasu, więc nawet drastyczne optymalizacje zastosowane wobec pozostałej jego części dadzą raczej nikły efekt.
Optymalizację dodatkowo komplikuje wiele innych spraw, jak choćby to, że:
Po uwzględnieniu tych uwag wychodzi na to, że najbezpieczniejszym rodzajem optymalizacji jest ten, który polega na odpowiednim refaktoringu kodu – zwłaszcza, jeśli jest on uzasadniony przeprowadzonym uprzednio profilowaniem. Może się bowiem okazać, że najbanalniejsza zmiana, jak np. wydzielenie globalnego obiektu tworzonego w często wywoływanej funkcji, daje natychmiastowy i zauważalny efekt. A jest to efektem jedynie tego, iż optymalizacja była po prostu zastosowana we właściwym miejscu.
I na pewno nie była “przedwczesna” ;P
`… używanie przesunięcia bitowego do obliczania potęg liczb całkowitych dla podstawy 2.` – litości! :)
Moim zdaniem pisząc kod należy go pisać tak żeby był czytelny i łatwy do zmieniania. A następnie uruchomić profiler i sprawdzić czy takie podejście się sprawdziło. Jeśli nie – poszukać krytycznych punktów i zoptymalizować je na ile potrzeba.
Jeśli zaczniemy od wstawiania wszędzie superwydajnych algorytmów, może się okazać że aplikacja będzie o mikrosekundy szybsza, ale kod zamiast 10K linii będzie miał 50K, w dodatku nieczytelnych i niemożliwych do modyfikacji bez rozwalania wszystkiego.
Ale to tylko moje zdanie…
@MSM: dlatego jestem za hasłem “Premature optimization is like premature ejaculation” ;) Takich “optymallizatorów” kodu trzeba od razu sprowadzać do parteru, bo piszą pół roku kod 10us szybszy, który po zmianie 1 stałej w programie magicznie zdycha albo wykonuje się 2x tyle co kod “nieoptymalny”.