Faszyści optymalizacji

02 Jun 2008

Większość kodu, który w życiu wytworzyłem wylądowała w koszu. Z różnych powodów. Najczęściej były to tylko prototypy, rzeczy pisane dla sprawdzenia "czy tak się da", kunsztowne acz kompletnie niepraktyczne bibeloty tworzone dla przyjemności, w końcu kod pisany dla samej nauki kodowania. Wszystkie powyższe mają jedną cechę wspólną - były z przeznaczenia tymczasowe. Jest jednak jeszcze jedna kategoria oprogramowania kompostowego - programy i biblioteki zbytnio zoptymalizowane pod kątem wydajności. Nie były one bynajmniej pisane jako tymczasowe rozwiązania, wręcz przeciwnie - miały przetrwać po wsze czasy (czyli do najbliższej zimy atomowej) jako wzór solidnej roboty inżynieryjnej. Niemniej, skończyły w koszu. Wszystkie, co do jednego. Nie ostało się żadne rozwiązanie optymalizacyjne.

Bo optymalizowały nie to, co trzeba. Stara zasada mówi, że optymalizować należy w pierwszej kolejności to, co optymalizować się opłaci najbardziej. A najbardziej czasochłonne nie jest odpytywanie baz danych czy web serwisów. Najbardziej czasochłonne jest samo tworzenie oprogramowania. Jeśli jakaś warstwa cache wprowadza dodatkowe utrudnienia w pisaniu programu (odpytywanie o czystość, sprawdzanie timeoutów, synchronizacja blokad) to optymalizacja ma zysk ujemny. Można się nie zgadzać twierdząc, że program pisze się raz, a będzie wykonywany z limesem w nieskończoności. Można, tylko że to nie prawda. Programu zazwyczaj nie pisze się raz. Program poprawia się latami. Program dostosowuje się do zmian i nowych wymagań. Developerzy przychodzą i odchodzą, a program nadal się zmienia. Niedowiarków niech przekona argument arytmetyczny. Hosting przyzwoitego serwera to koszt $300 miesięcznie, co daje ok. 0,012 centa za sekundę. Jeśli zamierzamy dzięki optymalizacji zaoszczędzić każdorazowo 500ms i algorytm zostanie użyty 1000 razy przez 1000 różnych klientów to właśnie oszczędziliśmy oszałamiającą kwotę $6. Przy czym oszczędność jest i tak pozorna, bo i tak nikt nam tych $6 nie zwróci.

Bo nikt nie potrafił ich poprawić. Każdy dodatkowy element programu to kolejna rzecz, o której musisz pamiętać podczas jego tworzenia. Ponadto, Twój kawałek kodu będzie najprawdopodobniej poprawiany później przez inną osobę. Biorąc pod uwagę, że oprogramowanie ze swej natury jest skomplikowane, a przeciętny człowiek może jednocześnie śledzić maksymalnie od 5 do 7 wątków, dodatkowe mechanizmy optymalizacyjne podnoszą prawdopodobieństwo pomyłki i zwiększają koszta naprawy błędów. Poza tym, kod optymalizujący jest najczęściej trudny, a...

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. Brian W. Kernighan

Bo nie nadążały za zmianami. Zmiany nadejdą - to jedyna pewna rzecz w inżynierii oprogramowania. Nigdy nie ma na nic czasu - to inny pewnik. Gdy już nadejdą, będziesz zwijał się jak w ukropie by dostosować swoją logikę biznesową do nowych wymagań. Jeśli pokusiłeś się o warstwę optymalizacji to będziesz musiał poprawić również i ją. W efekcie w moim kodzie przybywało swego czasu znaków //, gdzie "tymczasowo" wyłączałem obsługę jakiegoś bufora. Tylko nie oszukujmy się - nie jest to już optymalizacja a raczej obfuskatyzacja ;-)

Bo kosztowały za dużo. Dobrzy programiści to tacy, którzy swoje zadania kończą (i robią to w nie najgorszym stylu). Napisanie dobrej warstwy optymalizacyjnej jest możliwe, acz szalenie kosztowne. Trzeba przewidzieć możliwe kierunki zmian, uodpornić kod na zmianę liczności relacji, zadbać o problem aktualności cache, zapewnić synchronizację dostępu i ew. blokowanie, obsłużyć ekspirowanie zarówno bufora jak i blokad. To wszystko są wielkie tematy, na które współczesna informatyka nie daje jednoznacznych odpowiedzi. Nawet jeśli jesteś übermastahaka, który rozwala takie drobnostki w parę godzin, to nadal jest to parę godzin, które poświęciłeś na realizację nieistniejącej potrzeby zamiast na przybliżaniu się do kliknięcia checkboksa na swojej liście To do. A zaznaczone checkboksy to absolutnie jedyna rzecz, jaką management chce uzyskać od zespołu programistycznego. Za przewóz pszczół luzem nikt nie płaci, podobnie za puste checkboksy.

Bo zdrowy rozsądek to jeszcze nie optymalizacja. Czy napisanie algorytmu populującego strukturę drzewiastą tak, by nie wykonywać tylu zapytań do bazy, ile w drzewie węzłów można nazwać optymalizacją? Czy prywatny cache dla wyniku procedury składowanej lub web serwisu, czyszczony przy każdym requeście http jest mechanizmem optymalizacyjnym? Czy wielokolumnowy indeks albo ograniczenie ON DELETE CASCADE to optymalizacja? Nie. To najzwyklejszy zdrowy rozsądek, podobnie jak w przypadku tak oczywistym jak INT dla klucza surogatowego. I jasne jest (o ile ktoś nie spał na wykładach), że tak powinno być zrobione od początku.

Faszystów optymalizacji można spotkać na każdym kroku. Dość przejrzeć kilka portali tematycznych w dowolnym znanym języku - im rozleglejszy temat tym więcej ekspertów, którzy chętnie zalecą "usprawnienia". Szczególnie wdzięcznym przykładem jest rzekoma przewaga MySQL-a nad Postgresem. Faszyści optymalizacji nie rozumieją najczęściej takich pojęć jak transakcja czy MVCC, stąd s/n bliski zeru. Kolejny konik faszystów to łańcuchy tekstowe ujęte w apostrofy versus ujęte w cudzysłowy. Tu zysk optymalizacji obliczony w sposób jak powyżej jest jeszcze zabawniejszy. Następny dyżurny temat "specjalistów" to narzut wprowadzany przez programowanie obiektowe. Przykłady można mnożyć.
Faszyści optymalizacji zazwyczaj jeszcze nie pracują lub pracują na szeregowych stanowiskach, często wyróżniają się wiekiem. Nie to, żebym czuł z ich strony jakieś zagrożenie, ale hałas i hype, który tworzą wokół optymalizacji może się niektórym wydawać czymś istotnym. Pamiętam swoje gigantyczne zaskoczenie i niedowierzanie, gdy usunięto moje procedury buforujące. Wtedy, rozumując szybciej == lepiej miałem kierownika projektu za osobę niespełna rozumu, a wręcz szkodnika. Teraz jest to dla mnie jasne: optymalizujesz? - zajmij się lepiej robotą.

PS. A poza tym uważam, że Kartaginę należy spalić ;-)

Digg del.icio.us StumbleUpon Wykop Reddit Folksr

permalink | trackback | rss

 
 
Jajcuś

Bo optymalizować też trzeba umieć (co w większości przypadków sprowadza się bardziej do wiedzy co, a nie jak). Ale i tak dopiero wtedy, gdy optymalizacja jest potrzebna (gdy coś się przestaje wyrabiać i kupno lepszego cosia jest za drogie, albo nie rozwiązuje problemu).
W wielu przypadkach zamiast robić super-hiper frameworku, który może cache'ować wszystko, może lepiej wrzucić gdzieś może i mniej wydajne rozwiązanie, ale keszujące to, co najbardziej trzeba i w sposób przezroczysty, nie wymagający zmian w reszcie kodu. Np. często łatwiej i przez to efektywniej włączyć w httpd keszowanie wybranych URLi niż ładować do kodu aplikacji tysiące warunków, czy aby dana strona może być ładowana z bufora.

Khorne

"Oprogramowanie kompostowe", podoba mi się :)

A optymalizację stron WWW robi się tak jak Zed Shaw:

Finally, some people have asked me how my site survived a redditing, a techcrunching, and a slashdotting plus all the other hits. It’s very simple:

I don’t run Rails. I actually use another very nice Ruby project called webgen that generates the entire site, blog, feeds and all that offline, and then I rsync it onto a tiny 256M VM donated by RailsMachine This is then served up by nginx as pure static content.

str()

Jajcuś: problem z przeźroczystym buforowaniem jest taki, że gdy coś nagle przestaje działać, choć wszystkie znaki na niebie i ziemi wskazują, że powinno - o cachowaniu przypominasz sobie zazwyczaj na samym końcu, właśnie dlatego, że go nie widać. Dodatkowo kontrolowanie zewnętrznego cache jest trudne, niekiedy niemożliwe - nie wyobrażam sobie sterowania demonem http z poziomu aplikacji webowej. Najlepiej w ogóle nie musieć stosować takich ogólnych mechanizmów. A osobiście uważam, że kupno nowego cosia będzie i tak najtańszym rozwiązaniem.

Khorne: Świetne! Prawdziwi profesjonaliści potrafią wybrać właście narzędzia.

Your turn:

nick:
and?:
www (if any):
Wpisz kod:code
Faszyści optymalizacji optymalizacja programowanie