Warto zauważyć, że oryginalny cytat Knutha pochodzi z artykułu, który napisał, promując stosowanie go goto
w starannie wybranych i mierzonych obszarach jako sposób na wyeliminowanie punktów zapalnych. Jego cytat był zastrzeżeniem, które dodał, aby uzasadnić swoje uzasadnienie użycia goto
w celu przyspieszenia tych krytycznych pętli.
[...] znowu jest to zauważalna oszczędność w ogólnej szybkości działania, jeśli, powiedzmy, średnia wartość n wynosi około 20, a procedura wyszukiwania jest wykonywana około miliona razy w programie. Takie optymalizacje pętli [za pomocą gotos
] nie są trudne do nauczenia i, jak powiedziałem, są odpowiednie tylko w niewielkiej części programu, ale często przynoszą znaczne oszczędności. […]
I kontynuuje:
Konwencjonalna mądrość, którą podziela wielu dzisiejszych inżynierów oprogramowania, wzywa do ignorowania wydajności małych; ale uważam, że jest to po prostu przesadna reakcja na nadużycia, które widzą i są praktykowane przez głupich programistów, którzy nie mogą debugować ani utrzymywać swoich „zoptymalizowanych” programów. W uznanych dyscyplinach inżynieryjnych łatwa do uzyskania poprawa o 12% nigdy nie jest uważana za marginalną; i uważam, że ten sam punkt widzenia powinien dominować w inżynierii oprogramowania. Oczywiście nie zawracałbym sobie głowy wykonywaniem takich optymalizacji na jednym zdjęciu, ale jeśli chodzi o przygotowanie programów jakościowych, nie chcę ograniczać się do narzędzi, które odmawiają mi takich wydajności [tj. goto
Stwierdzeń w tym kontekście].
Należy pamiętać, jak użył słowa „zoptymalizowany” w cudzysłowach (oprogramowanie prawdopodobnie nie jest wydajne). Zwróć też uwagę, że krytykuje on nie tylko tych „grosza i funta-głupich” programistów, ale także ludzi, którzy reagują sugerując, że należy zawsze ignorować drobne niedociągnięcia. Na koniec do często cytowanej części:
Nie ma wątpliwości, że Graal wydajności prowadzi do nadużyć. Programiści marnują ogromne ilości czasu na myślenie lub martwienie się o szybkość niekrytycznych części swoich programów, a te próby zwiększenia wydajności mają w rzeczywistości silny negatywny wpływ na debugowanie i konserwację. Powinniśmy zapomnieć o małych wydajnościach, powiedzmy w 97% przypadków; przedwczesna optymalizacja jest źródłem wszelkiego zła.
... a następnie trochę więcej o znaczeniu narzędzi do profilowania:
Często błędem jest dokonywanie ocen a priori na temat tego, które części programu są naprawdę krytyczne, ponieważ z uniwersalnego doświadczenia programistów korzystających z narzędzi pomiarowych wynika, że ich intuicyjne przypuszczenia zawodzą. Po siedmiu latach pracy z takimi narzędziami doszedłem do przekonania, że wszystkie pisane od tej pory kompilatory powinny być zaprojektowane tak, aby zapewnić wszystkim programistom informację zwrotną wskazującą, które części ich programów kosztują najwięcej; w rzeczywistości ta informacja zwrotna powinna być dostarczana automatycznie, chyba że została specjalnie wyłączona.
Ludzie wszędzie nadużywali jego cytatu, często sugerując, że mikro-optymalizacje są przedwczesne, kiedy cały jego artykuł opowiadał się za mikro-optymalizacjami! Jedna z grup osób, które krytykował, a które powtarzają tę „konwencjonalną mądrość”, jak to ujął, że zawsze ignorują efektywność w małych grupach, często nadużywają jego cytatu, który pierwotnie był skierowany częściowo przeciwko takim typom, które zniechęcają do wszelkich form mikro-optymalizacji .
Był to jednak cytat na korzyść odpowiednio zastosowanych mikrooptymalizacji przy użyciu doświadczonej ręki trzymającej profilera. Dzisiejszy analogiczny odpowiednik może brzmieć: „Ludzie nie powinni na ślepo optymalizować swojego oprogramowania, ale niestandardowe alokatory pamięci mogą zrobić ogromną różnicę, gdy zostaną zastosowane w kluczowych obszarach w celu poprawy lokalizacji odniesienia” lub „ Odręczny kod SIMD przy użyciu Reprezentacja jest naprawdę trudna do utrzymania i nie powinieneś jej używać wszędzie, ale może zużywać pamięć znacznie szybciej, gdy zostanie odpowiednio zastosowana przez doświadczoną i kierowaną ręką. "
Za każdym razem, gdy próbujesz promować starannie zastosowane mikro-optymalizacje, jak promował Knuth powyżej, dobrze jest wrzucić zastrzeżenie, aby zniechęcić nowicjuszy do zbytniego podniecenia i ślepego próbowania optymalizacji, na przykład przepisywania całego oprogramowania do użytku goto
. Po części to właśnie robił. Jego cytat był faktycznie częścią wielkiego zastrzeżenia, tak jak ktoś, kto przeskakuje motocyklem przez płonące ognisko, może dodać zastrzeżenie, że amatorzy nie powinni próbować tego w domu, jednocześnie krytykując tych, którzy próbują bez odpowiedniej wiedzy i sprzętu i otrzymują obrażenia .
To, co uznał za „przedwczesne optymalizacje”, to optymalizacje stosowane przez ludzi, którzy faktycznie nie wiedzieli, co robią: nie wiedzieli, czy optymalizacja jest naprawdę potrzebna, nie mierzyli odpowiednimi narzędziami, być może nie rozumieli natury ich kompilator lub architektura komputera, a przede wszystkim były „głupie grosze i funty”, co oznacza, że przeoczyli duże możliwości optymalizacji (zaoszczędzenia milionów dolarów), próbując uszczypnąć grosze, a wszystko to podczas tworzenia kodu nie może dłużej skutecznie debugować i utrzymywać.
Jeśli nie pasujesz do kategorii „grosz-i-funt-głupi”, to nie optymalizujesz przedwcześnie według standardów Knutha, nawet jeśli używasz goto
w celu przyspieszenia pętli krytycznej (co jest mało prawdopodobne aby pomóc znacznie w starciu z dzisiejszymi optymalizatorami, ale gdyby tak było, i to w naprawdę krytycznym obszarze, nie optymalizowałbyś przedwcześnie). Jeśli faktycznie stosujesz to, co robisz w obszarach, które są naprawdę potrzebne i naprawdę odnoszą z tego korzyści, to w oczach Knutha radzisz sobie świetnie.