Jakie jest znaczenie zasady optymalizacji programu 90/10?

67

Według Wikipedii reguła optymalizacji programu 90/10 stwierdza, że ​​„90% czasu wykonania programu spędza się na wykonywaniu 10% kodu” (patrz drugi akapit tutaj ).

Naprawdę tego nie rozumiem. Co to dokładnie znaczy? Jak 90% czasu wykonania można poświęcić tylko na wykonanie 10% kodu? A co z pozostałymi 90% kodu? Jak można je wykonać w zaledwie 10% czasu?

Rakshith Ravi
źródło
50
Niektóre części kodu mogą być wykonywane częściej niż inne części. W końcu do tego służą pętle. W praktyce niemal zawsze pewne części są wykonywane sposobem częściej niż inni.
Kilian Foth,
147
Poczekaj, aż usłyszysz zasadę 90/10 dotyczącą czasu trwania projektu oprogramowania: „90% projektu zajmie pierwsze 90% przydzielonego czasu; ostatnie 10% projektu zajmie pozostałe 90% przydzielonego czasu ”.
Paul D. Waite,
3
Zamieszanie tutaj: „czas jest wykonywany”. Zastanów się a++; for(i=0;i<100;i++){b++;} for(i=0;i<100;i++){print(xyz);}. Pewnie, że pierwsza pętla for wydaje dużo więcej niż pierwsza instrukcja, ale druga pętla for spędza około 1000 razy więcej czasu niż pierwsza instrukcja, ale nie wykonuje . To spędza ona czeka na druk . Istnieje więc różnica między czasem poświęconym na wykonanie a czasem, za który odpowiedzialny jest kod .
Mike Dunlavey,
32
@ Paul_D._Waite Myślałem, że 90% projektu zajęło 90% czasu, 90% tego, co pozostało, zajmuje kolejne 90% czasu, i tak dalej niespójna seria do wniosku, że żaden projekt nie jest kiedykolwiek ukończone lub całkowicie odinstalowane w mniej niż nieskończonym czasie.
nigel222,
9
Dla praktycznych przykładów kilka kodów, nad którymi pracowałem (modele naukowe), wykorzystało dużą ilość kodu (~ 10 000 wierszy) do odczytania i skonfigurowania modelu, a następnie wykonało pętlę przez kilkaset wierszy, aby wykonać obliczenia. Ale ta krótka pętla miała n ^ 4 (trzy wymiary przestrzeni powtarzane przez tysiące kroków czasowych), więc obliczenie zajęło kilka dni. Tak więc rzeczywisty stosunek był prawdopodobnie bardziej podobny do 99% / 1% :-)
jamesqf

Odpowiedzi:

184

W grze obowiązują dwie podstawowe zasady:

  • Niektóre kody są wykonywane znacznie częściej niż inne. Na przykład niektóre kody obsługi błędów mogą nigdy nie zostać użyte. Część kodu zostanie wykonana dopiero po uruchomieniu programu. Inny kod będzie wykonywany w kółko podczas działania programu.
  • Niektóre kody działają znacznie dłużej niż inne. Na przykład pojedynczy wiersz, który uruchamia zapytanie w bazie danych lub pobiera plik z Internetu, prawdopodobnie zajmie więcej niż miliony operacji matematycznych.

Reguła 90/10 nie jest dosłownie prawdą. Różni się w zależności od programu (i wątpię, czy istnieją jakieś podstawy do konkretnych liczb 90 i 10; ktoś prawdopodobnie wyciągnął je z powietrza). Ale chodzi o to, że jeśli chcesz, aby Twój program działał szybciej, prawdopodobnie tylko niewielka liczba linii ma znaczenie, aby tak się stało. Identyfikacja wolnych części oprogramowania jest często największą częścią optymalizacji.

Jest to ważny wgląd i oznacza, że ​​decyzje, które wydają się sprzeczne z intuicją nowego dewelopera, często mogą być prawidłowe. Na przykład:

  • Jest dużo kodu, że nie warto poświęcać czasu na „ulepszanie” , nawet jeśli robi to w głupi, uproszczony sposób. Czy możesz napisać bardziej wydajny algorytm wyszukiwania dla aplikacji XYZ? Tak, ale tak naprawdę proste porównanie każdej wartości zajmuje trywialny czas, mimo że istnieją tysiące wartości. Więc to po prostu nie jest tego warte. Nowym programistom może być trudno uniknąć niepotrzebnej optymalizacji, ponieważ w ich programie studiów tyle czasu poświęcono na napisanie „poprawnego” (czyli najbardziej wydajnego) algorytmu. Ale w prawdziwym świecie poprawnym algorytmem jest każdy, który działa i działa wystarczająco szybko.
  • Zmiany, które powodują, że kod jest znacznie dłuższy i bardziej złożony, mogą nadal przynosić zyski. Na przykład w aplikacji FOO warto dodać setki wierszy nowej logiki, aby uniknąć pojedynczego wywołania bazy danych.

źródło
6
Szczególnie ważne jest to, że dzięki funkcjom sortowania jest to znacznie szybsze (w czasie deweloperów) i łatwiejsze, aby głupie proste algo robiło dobre rzeczy we wszystkich przypadkach niż uzyskać eleganckie algo w pełni funkcjonalne i bezbłędne. (Tho jedyne powody, aby napisać coś w rodzaju algo zewnątrz acadamea są, jeśli budujemy bibliotekę lub pracujących na platformie bez niego ...)
StarWeaver
5
Myślę, że musisz dodać link do shouldioptimize.com :)
Ivan Kolmychek,
13
Myślę, że 90/10 pochodzi ze znanej zasady Pareto 80/20 en.wikipedia.org/wiki/Pareto_principle
fernando.reyes
2
@StarWeaver Dlatego tak ważne są języki, które sprawiają, że pisanie super wydajnych rodzajów jest tak łatwe lub łatwiejsze niż gówniane sortowanie bąbelkowe, jak C ++. Takie „wstępnie zapakowane” algorytmy i kod można naprawdę bardzo zoptymalizować bez powodowania złożoności w miejscu użycia.
Jak
6
@IvanKolmychek Ta strona wprowadza w błąd. Oczywiście, tego rodzaju analiza kosztów jest jednym z czynników, który należy wziąć pod uwagę, ale są też inne czynniki, takie jak wrażenia użytkownika. Możesz zaoszczędzić dużo pieniędzy, nie optymalizując, ale możesz również stracić dużo dochodów, jeśli ludzie opuszczą Twoją witrynę sfrustrowani.
jpmc26,
21

To nie jest prawo natury, ale praktyczna zasada zrodzona z szerokiego doświadczenia. Jest również znany jako reguła 80/20 i jest tylko przybliżeniem.

Pętle, gałęzie i inna kontrola przepływu.

Każde miejsce, które ma if, będzie miało jedną gałąź, która jest podejmowana częściej niż druga gałąź. W ten sposób więcej czasu na wykonanie przeznacza się na tę część programu, a nie na drugą część.

Każde miejsce, które ma pętlę, która działa więcej niż jeden raz, ma kod, który jest wykonywany więcej niż otaczający kod. Dlatego spędza się tam więcej czasu.

Jako przykład rozważ:

def DoSomeWork():
    for i in range(1000000):
        DoWork(i)
    except WorkExeption:
        print("Oh No!")

Tutaj print("Oh No!")będą one działać maksymalnie raz, a często nigdy, podczas gdy DoWork(i)wystąpią około miliona razy.

Caleth
źródło
7
Nazywanie tego regułą 80/20 może powodować zamieszanie w zasadzie Pareto , która ma szerszy zakres niż tylko programowanie. Może 90 i 10 to tylko wygodne liczby, które nie mają tego znaczenia.
trichoplax
29
Jest to przykład dyrektora Pareto. Obie pary liczb są jednakowo dowolne
Caleth
2
Istnieje zasada matematyczna podziału 80/20 w zasadzie Pareto. Nie są to tylko wyimaginowane postacie reprezentujące „dużo” i „trochę”.
Moyli
1
@Moyli - Tak, „Istnieje podział matematyczny na podział 80/20 ...”, ale w prawdziwym świecie nigdy (OK, przez przypadek, rzadko) będzie miał dokładnie 80/20.
Kevin Fegan
2
@trichoplax zasada pareto stosuje się tutaj bardzo dobrze. 20% przyczyn (wiersze kodu) powoduje 80% efektów (środowisko wykonawcze)
njzk2 25.10.16
16

Pętle

Kusi mnie, aby się tam zatrzymać! :-)

Rozważ ten program

1. do_something

2. loop 10 times
3.    do_another_thing

4.    loop 5 times
5.        do_more_stuff

Linia 1 jest wykonywana raz, podczas gdy linia 3 jest wykonywana 10 razy. Patrząc kolejno na każdą linię

1 1   0.8%
2 10  8.3%
3 10  8.3%
4 50 41.3%
5 50 41.3%

Dwie linie odpowiadają za 83% czasu wykonania (przy założeniu, że uruchomienie wszystkich linii zajmuje mniej więcej tyle samo. Zatem 40% programu zajmuje> 80%.

W przypadku większej liczby przykładów z prawdziwego świata wzrasta to, więc tylko niewielka liczba linii stanowi znaczną część czasu pracy.

Reguła 90/10 (lub, jak to się czasem mówi 80/20), jest „praktyczną zasadą” - tylko w przybliżeniu prawdziwą.

Zobacz także zasadę Pareto

Nick Keighley
źródło
2
Zamiast powiedzieć, że jest to tylko w przybliżeniu prawda, powiedziałbym, że w wielu przypadkach co najmniej 90% czasu zostanie poświęcone na wykonanie niewielkiej części kodu - co najwyżej 10%. Oczywiście byłoby możliwe posiadanie programów, w których wszystkie części zajmowałyby tyle samo czasu, ale jest to rzadkie.
supercat
+1 za odniesienie do zasady Pareto. Bardziej szczegółowe wyjaśnienia można znaleźć w tym fantastycznym wideo Vsauce .
Radu Murzea
5

Ponieważ pytano tylko o czas wykonania, ten przykład może być pomocny:

int main() {
    sleep(90); // approximately 10% of the program.
    // other 90% of the program:
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    sleep(1);
    return 0;
}

Mówiąc poważniej, oznacza to, że w prawdziwym kodzie prawie zawsze wywołuje się ciężką funkcję w pętli (zamiast sleep(90);), a przez pozostałe 10% czasu wykonuje się obliczenia jednoprzebiegowe.

Innym przykładem jest obsługa błędów w niektórych usługach HA. Każda wysoce dostępna usługa jest zaprojektowana do pracy przez nieograniczony czas w normalnych warunkach. Działa normalnie przez 99% czasu, ale czasami w przypadku błędu uruchamia obsługę błędów i odzyskiwanie, które mogą być jeszcze bardziej logicznie złożone niż sama usługa.

Siergiej
źródło
Fajnie, miałem nadzieję, że ktoś opublikuje ten ekstremalny przykład, który wyraźnie pokazuje różnicę.
djechlin
3

Rozumowanie 90/10 oznacza, że ​​niewielka część twojego kodu będzie powtarzana lub używana częściej niż inne. Jest to często używane do sugerowania, że ​​powinieneś skoncentrować 90% wysiłków związanych z programowaniem / optymalizacją na 10% kodu.

Pomyśl o zwykłym procesorze tekstu, takim jak Microsoft Word lub OpenOffice :

  • Okno dialogowe preferencji nie jest często używane;
  • Podprogramy, które rysują znaki, są używane przez cały czas.

To powiedzenie jest również używane w naukach o zarządzaniu ... To jest lekcja życia ... Znaczenie: skoncentruj większość wysiłków tam, gdzie daje to więcej rezultatów.

Lucas
źródło
6
Jeśli program Microsoft Word jest prosty, jaki jest przykład złożonego?
Peter Mortensen
@PeterMortensen, co nie ma sensu.
The Great Duck
@PeterMortensen Emacs, oczywiście.
muru
2

Wyobraź sobie taki program:

print "H"
print "e"
print "l"
print "l"
print "o"
for i=0 to 1,000,000
    print "How long now?"
next
print "B"
print "y"
print "e"

Zauważ, że jest tutaj 11 linii, w których 3 z 11 to pętla for, gdzie ile czasu spędza się na tym raczej małym kawałku kodu? Trochę, podczas gdy pozostałe 8 wierszy drukuje tylko jeden znak. Dlatego strzeż się, że chociaż jakiś kod może być krótki, to nie mówi ci, jak często jest wykonywany i ile czasu to zajmie.

JB King
źródło
0

Oprócz zapętlania, jak wspomniano w innych świetnych odpowiedziach, należy również wziąć pod uwagę zasady OSUSZANIA. Dobrze napisany kod zorientowany obiektowo zawiera wiele części wielokrotnego użytku. Te części, które są ponownie używane, z definicji są używane co najmniej dwa razy częściej niż coś, co jest wykonywane tylko raz. Jeśli masz dużo kodu OO, potencjalnie możesz wielokrotnie wykorzystywać kilka klas i metod, a kilka innych fragmentów kodu tylko raz.

Jak wspomniano w innych odpowiedziach, prawdopodobnie lepiej jest poświęcić wysiłek, aby kod, który jest używany częściej, był lepszy niż ulepszanie kodu, który jest używany tylko raz.

Marshall Tigerus
źródło
2
Możesz ponownie użyć dużo kodu, ale wszystko to może być wykonywane rzadko (choć nadal jest to kluczowe).
Peter Mortensen
@PeterMortensen „kluczowy, ale nie często” nie jest tym samym, co „ponownie używany prawie co sekundę i musi być tak szybki, jak to możliwe”
The Great Duck
@ TheGreatDuck i nie sądzę, że o to mu chodziło. Bo może mieć kod, który jest wykonywany rzadko, ale chcesz to się stało tak szybko, jak to możliwe. Na przykład, weźmy odzyskiwanie po błędzie - w zależności od aplikacji, może zająć trochę czasu (5 minut, godzina, może więcej) na ponowne uruchomienie systemu. Jeśli jednak powiedzmy, że system lotu napotkał błąd, naprawdę chcesz go jak najszybciej naprawić. Bo jeśli tego nie zrobi, „spadnie” i „rozbije się” w dosłownym tego słowa znaczeniu.
VLAZ
Wydaje się to sugerować, że DRY wymaga OO, co oczywiście nie jest prawdą. Ponowne użycie jest równie ułatwione dzięki bezpłatnym funkcjom itp.
podkreślenie_d
@vlaz to prawda, ale chodzi o to, że w samolocie ... WSZYSTKO musi biec szybko.
The Great Duck,
0

To nie jest reguła, to tylko koleś, który zredagował Wikipedię z kilkoma liczbami wyciągniętymi z powietrza i nazwał to regułą. Porównaj z zasadą Pareto, która jest bardziej utrwalona w innych kontekstach. Chciałbym zobaczyć, jakie badania zostały przeprowadzone (jeśli w ogóle) na temat dokładności tej „reguły”.

Ale w zasadzie odpowiedź na twoje pytanie brzmi: niektóre kody są wykonywane znacznie częściej niż inne. Pętle są często tego przyczyną. Innymi przyczynami są czasochłonne połączenia, np. Do zewnętrznych zasobów, takich jak usługi sieciowe lub nośniki danych.

Brad Thomas
źródło
Jest to uzasadnione, że ludzie używają ogólnej zasady.
The Great Duck
Jeśli sugerujesz, że jest to powszechnie stosowana zasada, chciałbym zobaczyć dowody na to również! A może to tylko kolejna opinia wyparta z powietrza, ale sugerowana jako faktyczna?
Brad Thomas
Jeśli faktycznie przeczytasz artykuł na Wikipedii, zobaczysz, że cytat, o który pyta pytający, ma następujący cytat: amazon.com/Every-Computer-Performance-Book-Computers/dp/ ... Nigdy nie widziałem go w użyciu, ale mój post był dla mnie niegrzeczny i lekceważący, więc odpowiedziałem. Oczywiście 10% to liczba, którą ktoś wymyślił. Mogę ustawić dowolną liczbę, czyniąc mój program nieefektywnym. Jednak to, czy jest to termin używany w inżynierii oprogramowania, wyraźnie nie podlega dyskusji, biorąc pod uwagę, jak wiele osób zgadza się na jego istnienie.
The Great Duck,
Nie zamierzam kupować książki tylko po to, by zobaczyć badania, do których rzekomo się odnosi ... czy możesz napisać z niej cytat, który pokazuje dowody? A może w rzeczywistości nic nie widziałeś?
Brad Thomas
1
@BradThomas: Dowodem przeciwko teorii, że ktoś, kto redagował Wikipedię, wymyślił zasadę 90-10, jest to, że była szeroko cytowana, z numerami 90 i 10, wiele lat przed istnieniem Wikipedii; prawdziwa zasada nie polega na tym, że dokładnie 10% kodu stanowi 90% środowiska wykonawczego, ale raczej, że w większości programów niewielka część kodu - 10% lub mniej , odpowiada za tak dużą część środowiska wykonawczego - -90% lub więcej, że nawet 10% poprawa wydajności tej małej części kodu skróciłaby całkowity czas wykonania ponad 1000-krotną poprawę we wszystkim innym.
supercat
0

Jest to reinterpretacja „zasady Pareto”, która stwierdza: „w przypadku wielu zdarzeń około 80% skutków pochodzi z 20% przyczyn.”, Znanej również jako zasada 80/20. Ta zasada jest stosowana głównie do ekonomii, więc ma sens, aby była przeznaczona do programowania.

To tylko wzorzec obserwowany przez długi czas.

Oto bardzo fajny film o takich wzorach, a także wyjaśnia zasadę Pareto.

https://www.youtube.com/watch?v=fCn8zs912OE&ab_channel=Vsauce

imnota4
źródło