Come lo chiami quando cambi il tempo di esecuzione di Big O di una funzione [chiuso]


19

Diciamo che ho una funzione che ordina un database nel O(n^2)tempo. Voglio fare il refactoring in modo che funzioni nel O(n log(n))tempo, e così facendo cambierò il modo fondamentale di eseguire l'operazione, mantenendo i valori di ritorno e gli input equivalenti.

Come chiamo questa attività di refactoring?

"Accelerare-ifying" non sembra del tutto corretto, poiché puoi rendere un algoritmo più veloce senza modificare la grande velocità O alla quale è stato eseguito.

Anche la "semplificazione" non sembra giusta.

Come chiamo questa attività?

Aggiornare

La migliore risposta che ho potuto trovare è ridurre la complessità del tempo asintotico.


Gli algoritmi dovrebbero essere più veloci nella maggior parte dei casi d'uso dopo la modifica? Da notare, a volte è bello passare a una classe di complessità con scalabilità migliore anche con un risultato prestazionale medio atteso, solo per ottenere un comportamento prestazionale più coerente.
Nat

22
Questo non è refactoring
theonlygusti

6
A rigor di termini, la funzione che funziona nel O(log(n))tempo funziona anche nel O(n^2)tempo. Il significato di O(n^2)è "non cresce più velocemente del quadratico". Probabilmente intendevi Theta (log (n)) che significa "cresce più velocemente di log(n)". en.wikipedia.org/wiki/…
Džuris

4
<pedantic> non hai modificato il tempo di esecuzione di una funzione. una funzione è una relazione tra un dominio e un codomain ed esiste indipendentemente dai tuoi meschini tentativi umani di implementazione. invece hai trovato un algoritmo dalle prestazioni migliori che implementa la funzione </pedantic> <umano> buon lavoro </umano>
emory

5
@theonlygusti: dipende. Se la funzione in precedenza ha fatto una garanzia / garanzie sulle complessità, non è il refactoring. Se non ha garantito nulla, è refactoring. Se anche fosse esplicito il fatto di non fare garanzie, è soprattutto un refactoring.
galleria

Risposte:


44

In genere si chiama "ottimizzazione delle prestazioni" , ma non lo definirei "refactoring", poiché questo termine si riferisce in genere a modifiche del codice che non ne modificano il comportamento visibile . E un cambiamento in Big-O è sicuramente qualcosa che definirei un cambiamento visibile.

così facendo cambierò il modo fondamentale di eseguire l'operazione

In questo caso, l'ottimizzazione è una riscrittura di quella funzione. Non tutte le ottimizzazioni, anche se cambiano "Big-O", sono necessariamente una riscrittura, a volte sono necessari solo piccoli cambiamenti per ottenere un tale miglioramento, ma anche in questo caso, sono riluttante ad usare il termine "refactoring" per questo, perché tende a dare un'impressione sbagliata sulla natura del cambiamento.

EDIT: ho controllato l'elenco di refactoring di Fowler , e tra questi ~ 100 refactoring nominati, l'ultimo è chiamato "algoritmo sostitutivo" . Quindi se prendiamo questo come riferimento canonico, c'è una piccola area grigia in cui un'ottimizzazione della forma descritta potrebbe essere chiamata un tipo speciale di refactoring (ma IMHO non è tipico). Si noti inoltre che l'obiettivo di Fowler con tutti i refactoring era sempre quello di migliorare il design focalizzandosi sulla manutenibilità e evolvibilità del codice esistente senza riscriverlo e chiaramente non l'ottimizzazione delle prestazioni.


10
veramente? Penso che il refactoring sia corretto a meno che i requisiti non cambino. Quindi .. No se la funzione si chiama BubbleSort, ma sì se è solo Sort
Ewan

3
@Ewan Sì, dal punto di vista legale un refactoring può essere un'ottimizzazione delle prestazioni, ma il primo è di gran lunga troppo generale e non cattura adeguatamente l'impatto delle modifiche.
Deduplicatore

1
Ero a una presentazione iniziale del ragazzo che ha inventato e coniato Refactoring (Fowler?) E l'intera idea era collegata alla programmazione automatica e a verificabili miglioramenti verificabili del codice che non avevano alcun effetto sull'input vs output.
Sentinella

1
@Steve. Concordato. Stavo semplicemente aggiungendo al consenso che i miglioramenti di Big O rappresentano un miglioramento algoritmico, non miglioramenti nel modo in cui questi algoritmi sono rappresentati o mantenuti. In altre parole, l'attività è una riscrittura
Sentinel

1
@Steve: sì, lo sapevo, ho pensato di aggiungere una nota alla mia risposta. La mia modifica era solo una nota per chiarire che c'era una piccola area grigia.
Doc Brown,

13

Non penso che ci sia un termine standard, un uso comune è l' ottimizzazione sebbene il miglioramento , o l' accelerazione sarebbe anche corretto facendo il chiarimento che stai parlando di modifiche al codice e non di modifiche hardware.


7

Come altri hanno già detto, "ottimizzare" è il termine generale per migliorare le prestazioni di un algoritmo. Tuttavia, ottimizzare spesso significa migliorare i fattori costanti. Se volessi affermare in modo conciso ma chiaro che ho ridotto la complessità asintotica (tempo), direi che ho "migliorato le prestazioni asintotiche". A volte le persone lo descriveranno come "migliorare il ridimensionamento", ma questo è particolarmente ambiguo al giorno d'oggi.

Avvertenza : ridurre la complessità del tempo asintotico non è necessariamente la stessa cosa che ottimizzare in un contesto pratico . Spesso vengono utilizzati algoritmi asintoticamente non ottimali perché sulla gamma di input il programma è effettivamente esposto agli algoritmi meno ottimali che funzionano meglio.


5

Sarà dipendente dal contesto.

"Correzione di un bug delle prestazioni di runtime quadratico" è in genere ciò che vedo. Tuttavia, se ciò merita di essere risolto (una modifica del codice) dipende dal contesto.

Tieni presente che i database offrono molti strumenti per migliorare la complessità temporale. Ad esempio, per ottenere i primi N risultati da un database, basta dirlo. Quando si converte kludge inefficiente in chiamata ottimizzata integrata, la spiegazione sembra superflua.

Il motivo per cui considero un algoritmo con runtime quadratico per meritare una revisione del codice (discussione) non è tanto perché è lento (lento è relativo; quadratico è veloce rispetto all'esponenziale), ma perché l'intuizione umana (come i tuoi clienti, o colleghi programmatori) sono a disagio con una funzionalità software che si discosta troppo dal runtime lineare, a causa della mescolanza delle aspettative dalla vita quotidiana.

Molti reclami dei clienti sulle prestazioni del software rientrano in queste due categorie:

  • L'intero sistema (software e hardware) è stato specificato in base all'utilizzo stimato. La scorsa settimana, tutto funziona bene, una certa funzionalità ha richiesto meno di 5 secondi. Questa settimana, dopo l'installazione di un aggiornamento, la stessa funzionalità richiede più di 1 minuto.

    • Questo è un confronto con una performance precedentemente comparata. Il cliente mantiene le prestazioni future ad un metro assoluto di una scala temporale umana (da secondi a minuti).
  • Ho inviato 100 lavori al sistema. Perché l'elaborazione richiede 400 volte il tempo, rispetto al tempo impiegato per un singolo lavoro?

    • Il cliente si aspetta che i tempi di elaborazione siano lineari. In effetti, il cliente non può capire o accettare l'esistenza di attività più lente di quelle lineari.

Per questo motivo, un cliente considererà il tempo di esecuzione un bug se entrambi sono veri:

  • Più lento di lineare
  • Notevole (ovvero rientra nell'intervallo di tempo umano (più lungo di secondi o minuti) date le dimensioni tipiche dell'attività)

Argomenti legittimi che spiegano che un algoritmo di runtime quadratico non pone problemi (ovvero non merita una modifica del codice):

  • La dimensione dell'attività generalmente gestita da questa funzione di runtime quadratica è in qualche modo limitata
  • Dato l'intervallo di dimensioni tipico, il tempo di esecuzione (assoluto) effettivo è ancora abbastanza piccolo da essere ignorato
  • Se un utente tenta effettivamente di inviare un'attività sufficientemente grande da essere evidente, l'utente riceverà un messaggio di avviso sul lungo periodo di esecuzione
  • Gli utenti del sistema sono tutti esperti, quindi sanno cosa stanno facendo. Ad esempio, gli utenti di un'API dovrebbero aver letto la stampa fine sulla documentazione dell'API.

Molti algoritmi utili per lo sviluppo di applicazioni tipiche sono in effetti più lenti rispetto a quelli lineari (principalmente O (N log N), come nell'ordinamento), pertanto i software su larga scala cercheranno effettivamente di risolvere il problema, ordinando solo la parte pertinente del dati o utilizzare tecniche di filtro dell'istogramma (statistico) che ottengono un effetto simile.

Questo vale per i clienti di software, ma se si considera che anche gli utenti di una libreria di software o di una funzione API sono "clienti", la risposta sarebbe comunque valida.


2

Se l'algoritmo originale è stato implementato correttamente (o qualsiasi bug laddove irrilevante), allora "cambiare l'algoritmo" o "sostituzione dell'algoritmo" , poiché tali cambiamenti significano che lo stai facendo esattamente; sostituendo un algoritmo con diversa complessità temporale a quello precedentemente utilizzato.

Se la complessità del tempo precedente era dovuta a un bug nell'implementazione (ad esempio diciamo che stavi ripristinando accidentalmente il punto iniziale di un ciclo interno su una sequenza in modo che ciò che avrebbe dovuto essere O (n) diventasse O (n 2 )), quindi "correzione un bug di costo quadratico " o simile.

C'è una sovrapposizione, nel senso che in tal caso l'effetto sul codice è lo stesso se sai dall'inizio che il lavoro potrebbe essere fatto in O (n) time e il tempo O (n 2 ) era un errore, o se lo hai implementato deliberatamente per la prima volta in O (n 2 ) e poi ti sei reso conto che avrebbe funzionato correttamente senza azzerare il punto di partenza, sostituendo così un algoritmo O (n) con uno O (n 2 ).


1

Ottimizzazione della velocità di un ordine / ordini di grandezza. Sebbene questo sia un linguaggio matematicamente errato, trasmette al meglio l'idea che l'Ordine venga cambiato.

Migliorata la scalabilità. sentito anche.

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.