2009-04-02 16 views
9

Wczoraj uczestniczyłem w debacie z moim szefem na temat właściwej roli optymalizacji podczas budowania oprogramowania. Zasadniczo jego stanowisko było takie, że optymalizacja musi być głównym problemem podczas całego procesu rozwoju.Jak ważna jest optymalizacja?

Uważam, że należy podejmować właściwe decyzje algorytmiczne podczas opracowywania, ale nigdy nie należy liczyć cykli podczas opracowywania. W rzeczywistości tak mocno to odczuwam, musiałem odejść od rozmowy. Widziałem zbyt wiele złych decyzji dotyczących programowania w imię "optymalizacji", a zbyt wiele złych kodów zostało obronionych pod pretekstem "ta droga jest szybsza".

Co uważa społeczność StackOverflow.com?

+2

Nie trzeba gorącym pod kołnierzem z szefem. Trzeba tylko powiedzieć, że to jest twoje praktyczne doświadczenie, które zawsze przebija z góry przyjęte pomysły. Poza tym, IMO, nie ma nic straszniejszego niż ludzie, którzy zgadzają się na wszystko w 100%. –

+2

To jedna z tych debat, w których więcej razy ludzie nie rozmawiają tylko jeden obok drugiego. –

+0

@Steve: Tak, podobnie jak polityka i religia. Jednym ze sposobów na powiedzenie czegoś, z czym nikt nie może się kłócić, jest "Myślę, że XYZ" lub "W mojej opinii XYZ", a nie tylko "XYZ". To, że posiadasz opinię, jest niepodważalne. –

Odpowiedz

25

„Powinniśmy zapomnieć o małej wydajności, powiedzmy około 97% czasu: przedwczesny optymalizacji jest korzeniem wszelkiego zła Jednak nie powinniśmy przechodzić nasze możliwości w tym krytycznym 3%.”.

- Donald Knuth
+1

Nadal uważam, że jest to bardziej proporcja 80/20. –

+0

@Robert: Myślę, że zależy to w dużej mierze od tego, co uważasz za optymalizację, a po prostu za inteligentny projekt. –

+0

Myślę, że Knuth powinien dostać przedstawiciela. – MSN

5

Inżynier w całości, optymalizacja na końcu.

3

Ponieważ z wyjazdem z treściwy, powiem, że optymalizacja jest równie ważny jak wpływ nie robi.

0

Przedwczesna optymalizacja jest źródłem wszelkiego zła ... Istnieje ścisła równowaga między, ale chciałbym powiedzieć, 95% czasu, który trzeba zoptymalizować na końcu; istnieją jednak decyzje, które możesz podjąć wcześniej, aby pomóc w zapobieganiu problemom. Załóżmy na przykład, że mówimy o internetowej witrynie e-commerce. Musisz wyświetlić katalog. Teraz możesz pobrać wszystkie 100 000 przedmiotów i wyświetlić 50 z nich, lub możesz pobrać tylko 50 z bazy danych. Tego typu decyzje powinny być podejmowane z góry.

Cykl liczenia należy wykonywać tylko po zidentyfikowaniu problemu.

8

Optymalizacja jest prawie tautologicznie kompromisem: zyskujesz wydajność w czasie działania kosztem innych rzeczy (czytelność, łatwość konserwacji, elastyczność, czas kompilacji itp.). W związku z tym, naprawdę nie jest to dobry pomysł, chyba że wiesz, co jest kompromisem i dlaczego warto.

Co gorsza, myślenie o tym, "jak zrobić X szybko" może bardzo rozpraszać uwagę. Dużo energii w tym kierunku może łatwo doprowadzić do pomyłki w metodzie Y, która jest znacznie lepsza (i często szybsza - w ten sposób "optymalizacja" może spowolnić twój kod). Szczególnie, jeśli zbyt wiele z tego zrobisz w dużym projekcie od samego początku, oznacza to dużą dynamikę. Jeśli nie możesz sobie pozwolić na przezwyciężenie tego impetu, możesz łatwo zostać zablokowanym w złym projekcie, ponieważ nie możesz sobie pozwolić na czas na jego restrukturyzację. W ten sposób leżą smoki

To, o czym myśli twój szef, jest raczej kwestią pisania złego kodu za pośrednictwem nieodpowiednich reprezentacji i algorytmów. To nie jest tak samo jak optymalizacja, ale podejście, w którym nie zwraca się uwagi na odpowiednie struktury danych itp., Może spowodować, że baza kodów będzie wolna wszędzie i (podobnie jak powyższy "zamek") wymaga bohaterskiego wysiłku, aby naprawić .

Ogólnie rzecz biorąc, przedwczesna optymalizacja naprawdę szczerze jest okropnym pomysłem. Zwłaszcza, gdy kończy się to skomplikowanym, precyzyjnie dostrojonym, dobrze udokumentowanym (ponieważ jest to jedyny sposób, w jaki można to zrozumieć) fragment kodu, którego i tak nie użyjesz. A to nie jest nawet kwestia subtelnych błędów, które są często wprowadzane, gdy "optymalizowanie" powoduje, że cytowanie Knutha zamyka to dobrze.To właśnie dostaję za pisanie za dużo]

1

Myślę, że kod musi być przede wszystkim czytelny i zrozumiały. Tak więc optymalizacje, które są wykonywane, nie powinny odbywać się kosztem czytelności. Jednak optymalizacja często stanowi kompromis.

To, czy należy zoptymalizować kod, zależy od domeny aplikacji. Jeśli pracujesz na wbudowanym procesorze z zaledwie 8 MB pamięci, optymalizacja jest prawdopodobnie czymś, o czym każdy członek zespołu musi pamiętać podczas pisania kodu - optymalizując przestrzeń i prędkość.

Jednak wstępna optymalizacja nie przydaje się, chyba że system został wyraźnie określony i zrozumiany. Wynika to z faktu, że większość programistów nie podejmuje dobrych decyzji dotyczących optymalizacji, chyba że mogą one wpływać na cały system, w tym na czynniki architektoniczne procesora, takie jak pamięć podręczna, wątki sprzętowe, potoki itp.

1

Od 2 lat budowy wysoce zoptymalizowany kod Java (a potrzebne być zoptymalizowane w ten sposób) powiedziałbym, że nie jest to regułą, że czas spędzony reguluje optymalizacja:

  • optymalizacji na miejscu: 5% -10% swojego czasu na rzecz rozwoju, ponieważ musisz robić to niezliczoną ilość razy (za każdym razem, gdy musisz zmienić swój projekt)
  • optim gdy pracujesz: 2% czasu rozwoju (robisz to tylko raz)
  • wraca do niego i optymalizuje, gdy jest zbyt wolny: 30% czasu na rozwój, ponieważ musisz się zanurzyć do systemu

więc doszedłem do wniosku, że nie jest to właściwy czas i właściwy sposób, aby zoptymalizować: zrób to podmiot przez podmiot (klasy przez klasy, jeśli zajęcia, które mają jedno, dobrze zdefiniowane zadanie do wykonania i można je przetestować i zoptymalizować), dobrze przetestować, upewnić się, że logika działa, zoptymalizować tuż po tym i na zawsze zapomnieć o szczegółach implementacji tej jednostki.

3

Myślę, że "przedwczesna optymalizacja jest źródłem wszelkiego zła" musi być rozumiana dosłownie - nie mówi, kiedy jest przedwczesne, i nie mówi, że powinieneś zoptymalizować tylko na końcu. Po prostu nie za wcześnie. Ponadto "używaj właściwego algorytmu, O (n^2) a O (N)" jest nieco niebezpieczny, jeśli bierze się go dosłownie - ponieważ dla wielu problemów, N jest rzeczywiście mały, itd ...

Myślę, że zależy to od rodzaju oprogramowania, które wykonujesz: niektóre programy są takie, że każda część jest bardzo niezależna i może być zoptymalizowana oddzielnie. Ale nie zawsze tak jest. Dla wielu (większości?) Aplikacji, prędkość po prostu nie ma żadnego znaczenia, brutalna siła, ale oczywiście poprawna droga jest najlepsza. Ale w przypadku projektów, w których liczy się szybkość, często trzeba je brać pod uwagę na początku - może to kolejna możliwa interpretacja wypowiedzi Knutha: wiele aplikacji wcale nie musi być zoptymalizowanych, wystarczy wiedzieć, które z nich są potrzebne i planować z wyprzedzeniem.

15

Myślę, że przedwczesna wycena optymalizacji jest używana przez zbyt wielu, aby uniknąć myślenia o trudnych rzeczach dotyczących tego, jak dobrze aplikacja będzie działać. Gwarantuję, że użytkownicy chcą, abyś pomyślał o tym, jak zaprojektować go, aby działał jak najszybciej.

To nie znaczy, że powinieneś mierzyć wszystko, ale faza projektowania jest najłatwiejszym miejscem do optymalizacji, a nie kosztuje wiele czasu później.

Jest wiele sposobów na zrobienie czegokolwiek, powinieneś wybrać w fazie projektowania tę, która najprawdopodobniej najlepiej wykona (jeśli okaże się, że jest to jedna z okazji, gdy nie jest najlepsza, to zoptymalizować później).To powinno przeważyć potrzebę posiadania łatwego do odczytania kodu.

Jeśli nie rozważasz wydajności w fazie projektowania, nie będziesz miał dobrze zaprojektowanego systemu. Nie oznacza to, że powinno to być jedyną troską (chociaż w bazie danych oceniłbym ją jako trzecią pod względem ważności, zaraz po integralności i bezpieczeństwie danych), ale próbując naprawić system, w którym zastosowano słabe techniki, ponieważ programiści myśl, że łatwiej je zrozumieć, to koszmar. Bycie użytkownikiem takiego systemu, w którym musisz czekać na minuty za każdym razem, gdy chcesz przenieść się z jednego ekranu do drugiego, to koszmar (programiści powinni spędzać cały dzień codziennie przez co najmniej tydzień, używając swoich systemów!) Dla każdego, kto jest utknęły w źle zaprojektowanym systemie. Koszt jest mniejszy, aby zaprojektować prawidłowo niż naprawić później i biorąc pod uwagę wydajność ma kluczowe znaczenie dla prawidłowego projektowania.

Pracuję gdzieś, gdzie orginalni deweloperzy pili koolaid o przedwczesnej optymalizacji i robili wszystko, co uważali za najprostsze (ale w prawie każdym przypadku było to niewłaściwe z perspektywy wydajności). Teraz jesteśmy 10 razy większy niż trzy lata temu, a każdy ekran na każdej stronie trwa około 30 sekund (lub gorszy czas), a my tracimy klientów z tego powodu. Ale zmiana będzie zbyt trudna, ponieważ u podstawy zaprojektowali bazę danych, nie biorąc pod uwagę sposobu jej wykonania, a przeprojektowanie bazy danych z wieloma gigabajtami danych do nowej struktury jest zbyt czasochłonne i kosztowne. Gdyby zaprojektowano go tak, aby działał od początku, byłby łatwiejszy w utrzymaniu i szybszy dla klientów. Nie mówimy tu o potrzebie dostrojenia 10 najwolniejszych zapytań tutaj, mówimy o tym, że ogólna struktura wymaga drastycznej zmiany (która miałaby wpływ na praktycznie każde zapytanie przeciwko systemowi), aby działała dobrze.

Tak, nie rób mikro optymalizacji, dopóki nie będzie, ale proszę zrobić makro. Zastanów się, czy to najlepszy sposób, zanim podejmiesz decyzję o ścieżce. Nie pisz kursorów, aby trafić w tabele z milionami rekordów, gdy zrobi to polecenie oparte na zestawie. Nie staraj się mieć tak mało stolików, jak to tylko możliwe, ponieważ wydaje się to być bardziej eleganckim rozwiązaniem, gdy stoły przechowują różne przedmioty (takie jak ludzie, miejsca i pojazdy), powodując, że każde zapytanie trafia do tej samej tabeli i powoduje każde usunięcie aby sprawdzić wszystkie rodzaje tabel kluczy obcych, które nigdy nie będą miały rekordu dla tego typu encji (kasowanie jednego rekordu z głównej tabeli w naszej bazie zajmuje kilka minut, to jest prawdziwa radość, gdy coś idzie nie tak w imporcie (złe dane od klienta zazwyczaj) i musimy usunąć 200 000 pozwól mi powiedzieć).

3

Optymalizacja jest podstawową kwestią związaną z rozwojem, gdy masz dobry powód, by oczekiwać, że wydajność będzie niezmienna, jeśli optymalizacja jest problemem wtórnym.

To zależy w dużej mierze od rodzaju pisanego kodu, ale często istnieją lepsze powody, aby sądzić, że Twój kod będzie niezmiernie trudny w użyciu; lub utrzymywać; lub pełne błędów; lub późno; jeśli wszystkie te rzeczy stają się drugorzędne w stosunku do poprawy wydajności.

Złe kierownictwo mówi: "wszystkie te rzeczy są naszymi podstawowymi troskami". Dobrzy menedżerowie pracują, aby dowiedzieć się, jakie są zagrożenia dla tego projektu.

Oczywiście, dobry projekt musi brać pod uwagę wszystkie te rzeczy, a im wcześniej uzyskasz szacunkową wartość dowolnego z nich, tym lepiej. Jeśli mówi cały menadżer, to jeśli nigdy nie myślisz o tym, jak szybko twój kod będzie działał, to zbyt wiele kodu będzie wolne od psa, to on ma rację. Po prostu nie powiedziałbym, że to optymalizuje twój "podstawowy" problem.

Jeśli USP oprogramowania jest takie, że jest szybsze niż konkurencyjne, optymalizacja jest sprawą priorytetową. Dzięki doświadczeniu często można przewidzieć, jakie operacje będą wąskimi gardłami, od samego początku zaprojektować te z myślą o optymalizacji i mniej lub bardziej zignorować optymalizację w innym miejscu.Wiele projektów nie będzie tego potrzebować: będą wystarczająco szybkie bez większego wysiłku, pod warunkiem, że użyjesz rozsądnych algorytmów i nie zrobisz niczego głupiego. "Nie rób niczego głupiego" zawsze jest sprawą priorytetową, bez potrzeby wspominania o wydajności w szczególności.

1
  1. Przy opracowywaniu, tylko keep it simple. IMHO, większość problemów związanych z wydajnością jest spowodowanych przez nadmierną inżynierię - tworzenie gór z kretowisk, często z powodu "odpowiedniego algorytmu".

  2. Okresowo test warunków skrajnych z dużym zestawem danych, profilowaniem lub (moja ulubiona technika) ręcznym losowym próbkowaniem. Znajdź problem, napraw go. Znajdziesz inną, naprawisz to.

W ten sposób unikasz tworzenia się ślimaków (powolnych błędów), a kiedy one powstają, zabijasz je.

Dodano: Jeśli mogę tylko rozwinąć punkt 1. OO jest pozornie prawem ziemi, i to z pewnością ma dobre uzasadnienie. Niestety powoduje to, że wielu młodych programistów uważa, że ​​programowanie polega na posiadaniu dużej struktury danych, z warstwami na warstwach abstrakcji. Nie to, że są z natury złe, ale łączą to z naturalną tendencją do zakładania, że ​​czas, w którym coś się dzieje, jest w przybliżeniu proporcjonalny do liczby znaków, które trzeba wpisać, aby go przywołać, i że ta tendencja mnoży się przez warstwy (a poza tym maszyny są naprawdę szybkie), łatwo jest stworzyć doskonałą burzę odpadów cyklicznych.

0

Twój szef ma częściowo rację, optymalizacja musi być rozważana przez cały cykl rozwojowy, ale rzadko jest to podstawową troską. Również termin "optymalizacja" jest niejasny - jest przymiotnikiem "optymalizacji na ...", którym może być "pamięć", "szybkość", "użyteczność", "konserwowalność" i tak dalej.

Jednak OP ma rację, że cykle liczenia są bezcelowe w przypadku wielu projektów. W przypadku większości aplikacji komputerowych procesor nigdy nie jest wąskim gardłem. Ponadto IA32 nie jest spójny - co działało dobrze w jednej architekturze, słabo działa na innej. Liczenie cykli powinno być wykonywane tylko wtedy, gdy będzie to miało jakiś wpływ - zwykle w ograniczonym kodzie procesora lub kodzie z bardzo specyficznymi wymaganiami czasowymi.

Optymalizacja każdego rodzaju musi być zawsze poparta dowodami. Nigdy nie zakładaj niczego na temat systemu ani tego, jak zachowuje się kod. W idealnym świecie wydajność/ograniczenia aplikacji zostaną określone w początkowym projekcie produktu, a narzędzia do monitorowania wydajności aplikacji podczas jej tworzenia zostaną dodane na wczesnym etapie projektowania, aby kierować programistami podczas tworzenia produktu.

1

Cytat od przyjaciela: "Łatwiej jest sprawić, aby działający system był skuteczniejszy niż sprawny system pracy".

Uważam, że ważne jest, aby od samego początku używać inteligentnych praktyk i wzorców, ale aby system działał w małych przypadkach testowych, wykonaj analizę wydajności. Często obszary kodu, które mają słabą wydajność, nie są przewidywane na początku, więc uzyskaj prawdziwe dane, a następnie zoptymalizuj wąskie gardło 3% (lub 20% lub cokolwiek to jest).

1

Myślę, że twój szef ma o wiele więcej racji niż ty.

Zbyt często użytkownicy tracą doświadczenie tylko po to, aby zostać "odkrytymi na nowo" w ostatnich możliwych chwilach, gdy działania związane z wydajnością są nadmiernie kosztowne i nieefektywne. Lub gdy okaże się, że program wsadowy, który przetworzy dzisiejsze transakcje, wymaga czterdziestu godzin pracy.

Rzeczy takie jak organizacja baz danych, kiedy i kiedy tego nie robić, które SELECT są przykładami decyzji projektowych, które mogą spowodować lub złamać aplikację. Wciąż ryzykujesz, że jeden programista podejmie decyzję, by inaczej, źle interpretować lub po prostu nie rozumieć, co robić. Obserwacja wydajności podczas całego projektu zmniejsza ryzyko, że takie rzeczy się zdarzą. Pozwala także na zmianę decyzji projektowych, gdy jest taka potrzeba, bez narażania całego porodu na ryzyko.

"Musisz dokonać właściwych decyzji algorytmicznych podczas rozwoju" jest z pewnością prawdziwe, ale jak wielu programistów głównego nurtu jest w stanie to zrobić? Przeglądanie sieci w poszukiwaniu informacji nie gwarantuje znalezienia rozwiązania wysokiej jakości. "Prawo" można interpretować w ten sposób, że można wybrać zły algorytm, ponieważ jest on łatwy do zrozumienia i wdrożenia (= mniej czasu na opracowanie, niższy koszt) niż bardziej skomplikowany (= więcej czasu na opracowanie, wyższy koszt).

Wahadełko ilości a jakość jest prawie zawsze po stronie ilości, ponieważ więcej kodu na godzinę lub szybszy czas rozwoju oznacza pieniądze w krótkim okresie. Strona jakości oznacza pieniądze w długim okresie.

EDIT

This article omawia optymalizację wydajności i bardzo dokładnie.

Wydajny kaznodzieja Rico Mariana sums it up w krótkim oświadczeniu "nigdy nie poddawaj się przypadkowi."

Powiązane problemy