Qual è il significato della regola di ottimizzazione del programma 90/10?


67

Secondo Wikipedia, la regola del 90/10 dell'ottimizzazione del programma afferma che "il 90% del tempo di esecuzione di un programma viene impiegato nell'esecuzione del 10% del codice" (vedere il secondo paragrafo qui ).

Davvero non lo capisco. Cosa significa esattamente? Come si può impiegare il 90% del tempo di esecuzione solo eseguendo il 10% del codice? Che dire poi dell'altro 90% del codice? Come possono essere eseguiti solo nel 10% delle volte?


50
Alcune parti del codice possono essere eseguite più spesso di altre parti. Questo è ciò che serve per i loop, dopo tutto. In pratica, quasi sempre alcune parti vengono eseguite molto più spesso di altre.
Kilian Foth,

147
Aspetta di sentire la regola del 90/10 per la durata del progetto software: “Il 90% del progetto occuperà il primo 90% del tempo assegnato; l'ultimo 10% del progetto occuperà l'altro 90% del tempo assegnato ”.
Paul D. Waite,

3
Confusione qui: "il tempo è trascorso nell'esecuzione". Prendere in considerazione a++; for(i=0;i<100;i++){b++;} for(i=0;i<100;i++){print(xyz);}. Sicuramente il primo for-loop spende molto più della prima istruzione, ma il secondo for-loop spende ~ 1000 volte più tempo del primo for-loop, ma non in esecuzione . Lo spende in attesa di stampa . Quindi c'è una differenza tra il tempo impiegato per l' esecuzione e il tempo di responsabilità del codice .
Mike Dunlavey,

32
@ Paul_D._Waite Ho pensato che il 90% del progetto prendesse il 90% del tempo, il 90% di ciò che rimaneva impiega un altro 90% del tempo, e così via una serie non convergente alla conclusione che nessun progetto è mai finito o completamente cancellato in meno di un tempo infinito.
nigel222,

9
Per esempi pratici, un paio di codici su cui ho lavorato (modelli scientifici) hanno usato una grande quantità di codice (~ 10K righe) per leggere e impostare il modello, quindi ho fatto un giro attraverso alcune centinaia di righe per eseguire i calcoli effettivi. Ma quel ciclo breve era n ^ 4 (tre dimensioni dello spazio sono state ripetute attraverso migliaia di passaggi temporali), quindi ci sono voluti giorni per il calcolo. Quindi il rapporto effettivo era probabilmente più simile al 99% / 1% :-)
jamesqf

Risposte:


184

Ci sono due principi di base in gioco qui:

  • Alcuni codici vengono eseguiti molto più spesso di altri codici. Ad esempio, alcuni codici di gestione degli errori potrebbero non essere mai utilizzati. Alcuni codici verranno eseguiti solo all'avvio del programma. Altro codice verrà eseguito più volte durante l'esecuzione del programma.
  • L' esecuzione di alcuni codici richiede molto più tempo rispetto ad altri codici. Ad esempio, una singola riga che esegue una query su un database o estrae un file da Internet richiederà probabilmente più di milioni di operazioni matematiche.

La regola del 90/10 non è letteralmente vera. Varia in base al programma (e dubito che ci sia qualche base per i numeri specifici 90 e 10; qualcuno probabilmente li ha tirati fuori dal nulla). Ma il punto è che se hai bisogno che il tuo programma funzioni più velocemente, probabilmente solo un piccolo numero di righe è significativo per farlo accadere. L'identificazione delle parti lente del software è spesso la parte più grande dell'ottimizzazione.

Questa è una visione importante e significa che le decisioni che sembrano controintuitive per un nuovo sviluppatore possono spesso essere corrette. Per esempio:

  • C'è un sacco di codice che non vale la pena dedicare del tempo a "migliorare" , anche se sta facendo le cose in modo stupido e semplicistico. Potresti scrivere un algoritmo di ricerca più efficiente per l'applicazione XYZ? Sì, ma in realtà un semplice confronto di ogni valore richiede una banale quantità di tempo, anche se ci sono migliaia di valori. Quindi non ne vale la pena. Può essere difficile per i nuovi sviluppatori evitare l'ottimizzazione non necessaria, perché nel loro corso di laurea è stato dedicato molto tempo alla stesura dell'algoritmo "corretto" (che significa più efficiente). Ma nel mondo reale, l'algoritmo corretto è quello che funziona e funziona abbastanza velocemente.
  • Le modifiche che rendono il codice molto più lungo e più complesso possono comunque essere una vittoria delle prestazioni. Ad esempio, nell'applicazione FOO può valere la pena aggiungere centinaia di righe di nuova logica, solo per evitare una singola chiamata al database.

6
Di particolare nota, con cose come le funzioni di ordinamento, è molto più veloce (in tempo di sviluppo) e più facile fare in modo che un algo semplice stupido faccia la cosa giusta in tutti i casi piuttosto che ottenere un algo elegante completamente funzionale e senza errori. (Le uniche ragioni per scrivere una sorta di algo al di fuori di Acadamea sono se stai costruendo una libreria o stai lavorando su una piattaforma senza una ...)
StarWeaver

5
Penso che devi aggiungere il link a shouldioptimize.com :)
Ivan Kolmychek,

13
Penso che il 90/10 provenga dal noto Principio di Pareto 80/20 en.wikipedia.org/wiki/Pareto_principle
fernando.reyes,

2
@StarWeaver Ecco perché le lingue che rendono la scrittura di tipi super efficienti tanto semplici quanto più semplici di una sorta di bolla scadente sono importanti lì, come C ++. Tali algoritmi e codice "preconfezionati" possono essere ottimizzati in modo molto pesante senza causare complessità nel punto di utilizzo.
Yakk,

6
@IvanKolmychek Quel sito è fuorviante. Certo, questo tipo di analisi dei costi è un fattore da considerare, ma ci sono altri fattori come l'esperienza dell'utente. Potresti risparmiare un sacco di soldi non ottimizzando, ma potresti anche perdere un sacco di entrate se le persone lasciano il tuo sito frustrato.
jpmc26,

21

Questa non è una legge della natura, ma una regola empirica nata da una vasta esperienza. È anche conosciuta come la regola 80/20 ed è sempre e solo una approssimazione approssimativa.

Loop, rami e altri controlli di flusso.

Ogni posto che ha un if, avrai un ramo che viene preso più spesso dell'altro ramo. Pertanto, si impiega più tempo per l'esecuzione di quella parte del programma e non l'altra parte.

Ogni posto che ha un ciclo che gira più di una volta, hai un codice che viene eseguito più del codice circostante. Quindi più tempo viene trascorso lì.

Ad esempio, considera:

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

Qui il test print("Oh No!")verrà eseguito solo una volta al massimo, e spesso mai, mentre DoWork(i)si verificherà circa un milione di volte.


7
Chiamarla regola 80/20 può causare confusione con il principio di Pareto , che si applica più ampiamente della semplice programmazione. Forse 90 e 10 sono solo numeri convenienti che non hanno questa sovrapposizione di significato.
trichoplax,

29
È un'istanza del principale di Pareto. Entrambe le coppie di numeri sono ugualmente arbitrarie
Caleth,

2
C'è una base matematica per la divisione 80/20 nel principio di Pareto. Non sono solo alcune figure immaginarie che rappresentano "molto" e "un po '".
Moyli,

1
@Moyli - Sì, "Esiste una base matematica per la divisione 80/20 ...", ma nel mondo reale non sarà mai (OK, per coincidenza, raramente) esattamente 80/20.
Kevin Fegan,

2
@trichoplax il principio di pareto si applica molto bene qui. Il 20% delle cause (le righe del codice) causa l'80% degli effetti (il runtime)
njzk2

16

Loops.

Sono tentato di fermarmi qui! :-)

Considera questo programma

1. do_something

2. loop 10 times
3.    do_another_thing

4.    loop 5 times
5.        do_more_stuff

La riga 1 viene eseguita una volta mentre la riga 3 viene eseguita 10 volte. Guardando ogni riga a turno

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

Due righe rappresentano l'83% del tempo di esecuzione (supponendo che tutte le righe richiedano lo stesso tempo per l'esecuzione. Pertanto, il 40% del programma richiede> 80%.

Con esempi più ampi del mondo reale questo aumenta, quindi solo una piccola quantità di righe rappresenta gran parte del tempo di esecuzione.

La regola 90/10 (o come viene talvolta definita 80/20) è una "regola empirica" ​​- solo approssimativamente vera.

Vedi anche Principio di Pareto


2
Invece di dire che è solo approssimativamente vero, direi che in molti casi, almeno il 90% del tempo sarà impiegato per eseguire una piccola parte del codice, al massimo il 10%. Ovviamente sarebbe possibile avere programmi in cui tutte le porzioni impiegassero la stessa quantità di tempo per l'esecuzione, ma questo è raro.
supercat

+1 per fare riferimento al Principio di Pareto. Una spiegazione più approfondita può essere vista in questo fantastico video Vsauce .
Radu Murzea,

5

Come è stato chiesto solo del tempo di esecuzione, questo esempio potrebbe essere utile:

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;
}

Se essere un po 'più serio, significa che nel codice della vita reale quasi sempre si chiama una funzione pesante in un ciclo (anziché sleep(90);), mentre il resto del 10% delle volte si eseguono calcoli a passaggio singolo.

Un altro esempio è la gestione degli errori in alcuni servizi HA. Qualsiasi servizio a disponibilità elevata è progettato per funzionare per un tempo infinito in condizioni normali. Funziona normalmente il 99% delle volte, ma occasionalmente, in caso di errore, esegue una gestione e un recupero degli errori, che possono essere persino più logicamente complessi del servizio stesso.


Bello, speravo che qualcuno potesse pubblicare questo esempio estremo, che mostra chiaramente la differenza.
Djechlin,

3

Il ragionamento 90/10 significa che una piccola parte del tuo codice verrà ripetuta o utilizzata più di altre. Questo è spesso usato per suggerire che dovresti concentrare il 90% del tuo sforzo di sviluppo / ottimizzazione in questo 10% del tuo codice.

Pensa a un normale elaboratore di testi, come Microsoft Word o OpenOffice :

  • La finestra di dialogo delle preferenze non è molto usata;
  • Le subroutine che disegnano i personaggi vengono usate continuamente.

Questo detto è usato anche nelle scienze gestionali ... Questa è una lezione per la vita stessa ... Significato: concentra la maggior parte dei tuoi sforzi dove ti dà più risultati.


6
Se Microsoft Word è semplice, qual è un esempio complesso?
Peter Mortensen,

@PeterMortensen che non ha senso.
The Great Duck,

@PeterMortensen Emacs, ovviamente.
Muru,

2

Immagina un programma come questo:

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"

Notate come ci sono 11 righe qui dove 3 su 11 sono il ciclo for, dove quanto tempo viene impiegato su questo pezzo di codice piuttosto piccolo? Abbastanza un po 'mentre le altre 8 righe stanno semplicemente stampando un singolo carattere. Quindi, attenzione che mentre un po 'di codice può essere breve, ciò non ti dice quanto spesso viene eseguito e quanto tempo ci vorrà.


0

Oltre al looping, come menzionato da altre grandi risposte, ci sono anche principi DRY da considerare. Ben scritto, il codice orientato agli oggetti ha molte parti riutilizzabili. Quelle parti che vengono riutilizzate, per definizione, vengono utilizzate almeno due volte più spesso di qualcosa che viene eseguito una sola volta. Se disponi di molto codice OO, potresti riutilizzare alcune classi e metodi molte volte e qualche altra parte di codice una sola volta.

Come menzionato in altre risposte, è probabilmente meglio dedicare uno sforzo per rendere il codice che viene usato più spesso meglio che migliorare il codice che viene utilizzato solo una volta.


2
Potresti riutilizzare molto codice, ma tutto potrebbe essere eseguito di rado (pur essendo ancora cruciale).
Peter Mortensen,

@PeterMortensen "cruciale ma non spesso" non è lo stesso di "riutilizzato quasi ogni secondo e deve essere il più veloce possibile"
The Great Duck

@TheGreatDuck e non credo sia quello che intendeva dire. Perché puoi avere un codice che viene eseguito raramente ma vuoi che avvenga il più velocemente possibile. Per un esempio, prendiamo il recupero degli errori - a seconda dell'applicazione, potrebbe essere necessario attendere un po 'di tempo (5 minuti, un'ora, forse di più) affinché il sistema sia nuovamente operativo. Tuttavia, se, per esempio, un sistema di volo rileva un errore, lo desideri davvero il più velocemente possibile. Perché se non lo fa "scenderà" e "schiantarsi" in un senso molto letterale.
VLAZ,

Ciò sembra implicare che DRY richiede OO, il che ovviamente non è vero. Il riutilizzo è ugualmente facilitato da funzioni gratuite, ecc.
underscore_d

@vlaz è vero, ma il fatto è che in aereo ... TUTTO deve correre veloce.
The Great Duck,

0

Non è una regola, è solo un tipo che ha modificato Wikipedia con un paio di numeri tirati fuori dal nulla e l'ha definita una regola. Confronta con il principio di Pareto, che è più saldamente stabilito in altri contesti. Mi piacerebbe vedere quali ricerche sono state fatte (se presenti) sull'accuratezza di questa "regola".

Ma sostanzialmente la risposta alla tua domanda è che alcuni codici vengono eseguiti molto più frequentemente di altri codici. I loop sono spesso la ragione di ciò. Altri motivi sono le chiamate che richiedono tempo, ad esempio a risorse esterne come servizi Web o supporti di archiviazione.


È una cosa legittima che le persone usano come regola empirica.
The Great Duck,

Se stai suggerendo che questo è un uso diffuso come regola empirica, sarei interessato a vedere prove anche per quello! O è solo un'altra opinione estratta dal nulla ma implicita come fattuale?
Brad Thomas,

Se effettivamente leggessi l'articolo di Wikipedia vedresti che la citazione a cui fa riferimento il richiedente ha questa citazione: amazon.com/Every-Computer-Performance-Book-Computers/dp/… non l'ho mai visto personalmente in uso, ma il tuo post mi è sembrato maleducato e respinto secondo me, quindi ho risposto. Ovviamente il 10% è un numero inventato da qualcuno. Posso renderlo qualunque numero che voglio rendendo il mio programma inefficiente. Tuttavia, indipendentemente dal fatto che sia un termine usato nell'ingegneria del software, non è chiaramente discutibile visto che quante persone qui concordano sulla sua esistenza.
The Great Duck,

Beh, non ho intenzione di andare a comprare il libro solo per vedere la ricerca a cui si presume si riferisca ... puoi pubblicare un preventivo da esso che mostra le prove? O non ne hai visto nessuno?
Brad Thomas,

1
@BradThomas: l'evidenza contro la teoria secondo cui una regola del 90-10 è stata inventata da qualcuno che stava modificando Wikipedia è che è stata ampiamente citata, con i numeri 90 e 10, molti anni prima dell'esistenza di Wikipedia; il vero principio non è che esattamente il 10% del codice rappresenti il ​​90% del tempo di esecuzione, ma piuttosto che nella maggior parte dei programmi una piccola porzione del codice - il 10% o meno , rappresenta una parte così grande del tempo di esecuzione - -90% o più che anche un miglioramento del 10% nelle prestazioni di quella piccola parte del codice ridurrebbe i tempi complessivi di esecuzione più di un miglioramento 1000x in tutto il resto.
supercat,

0

È una reinterpretazione del "principio di Pareto", che afferma "per molti eventi, circa l'80% degli effetti deriva dal 20% delle cause", noto anche come regola 80/20. Questa regola si applica principalmente all'economia, quindi ha senso che venga riproposta per la programmazione.

È solo uno schema che è stato osservato per un lungo periodo di tempo.

Ecco un video molto bello su modelli come questo, e spiega anche il principio di Pareto.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.