Best practice per ridurre i bug durante l'ottimizzazione del codice [chiuso]

-1

Oggi ho lavorato su un programma semplice da un libro di testo.

Anche se ho risolto la domanda con sicurezza e una soluzione chiara e robusta, la soluzione non era perfetta in quanto aveva passaggi che erano ridondanti.
Più ho ottimizzato e ho cercato di renderlo perfetto:

Il codice è diventato più:
 - illeggibile  - Buggy

Sono diventato:
- Meno fiducioso della soluzione
- Più frustrato

Esiste un modo corretto per gestire le ottimizzazioni in modo da non perdere la tua mente e il tuo tempo, o se dovessi smettere di ottimizzare se la soluzione non è pulita.

    
posta Janarth K 12.02.2017 - 23:28
fonte

4 risposte

1

Non cercare la perfezione. Riconoscere che c'è un equilibrio che deve essere raggiunto tra il codice "buono" e il codice "perfetto".

Diciamo che il codice funziona bene, è leggibile, gestibile, facile da usare, ma ha una piccola manciata di cose che potrebbero non essere al 100% come vorresti. Se provi a rifattorizzare quelle poche cose ma finisci per scavarti in una tana di coniglio, allora il codice sarebbe stato meglio se lo avessi appena lasciato nel suo stato "buono", giusto?

In realtà, questi casi di solito indicano che un'architettura migliore all'inizio sarebbe stata migliore, ma a questo punto potrebbe non avere molto senso tornare indietro e "sistemare tutto".

Per ogni singolo progetto su cui lavori, te ne andrai con alcuni pensieri "Avrei potuto fare X meglio" - e questo è positivo. Apprendi da loro e applica ciò che hai appreso nel tuo prossimo progetto. È un ciclo infinito di programmazione. Nessun progetto è mai "perfetto" e riconoscere che "colpire l'equilibrio" è ciò che devi davvero fare è la chiave della tua sanità mentale. Impara da questo, sii felice con un lavoro ben fatto (anche se non perfetto), e riprova la prossima volta.

Per questo particolare progetto, sembra che sarebbe bello fare un passo indietro e dire "se dovessi fare tutto di nuovo, cosa avrei potuto fare in modo diverso, in particolare per evitare che l'area di questo problema fosse più buggata e contribuendo a un codice meno leggibile quando provo a risolverlo? " Se riesci a capirlo, sembra proprio che sia il buono da asporto.

Il problema arriva quando le persone non riescono ad essere retrospettive su queste cose. La buona esperienza è costruita in questo modo, ma se una persona non è disposta a riflettere su cosa avrebbe potuto essere fatto meglio, non lo ricorderanno mai e miglioreranno le loro abilità per la prossima volta.

    
risposta data 12.02.2017 - 23:44
fonte
2

L'unica best practice che conosco per ridurre i bug durante l'ottimizzazione del codice (o per qualsiasi tipo di refactoring, se è per questo) è test appropriato . (Che include test approfonditi .)

Quindi, prima devi far funzionare il tuo codice, quindi hai tutti i test in atto che dimostrano che funziona correttamente, (o prima fai i test, poi scrivi il tuo codice, se sei della persecuzione del TDD, ) e poi inizi a modificare le cose. E con ogni modifica, riesegui i tuoi test. In questo modo, se il tuo tweak rompe qualcosa, lo prendi.

Ovviamente, mentre modifichi le cose, potresti avere idee su più test per testare in particolare le cose che potrebbero modificare il tuo tweak. Quando ti viene in mente un'idea del genere, ferma ciò che stai facendo, accantonare le modifiche apportate, aggiungi quel test, assicurati che tutto funzioni, e quindi elimina le modifiche apportate e procedi.

    
risposta data 13.02.2017 - 00:18
fonte
2

Evita pre-ottimizzazione

La pre-ottimizzazione si verifica quando si presume che un pezzo di codice sia inefficiente sulle risorse e quindi si concentri sul suo fixing, senza nemmeno controllare se si tratta di un problema.

Si può sprecare un bel po 'di tempo su questo, e potrebbe potenzialmente danneggiare le vostre decisioni di progettazione. Se hai qualche problema, profila la tua applicazione.

Evita l'ottimizzazione Mico

Mico-optimization è un tentativo di risparmiare risorse provando a rimuovere le cose a nudo.

Un esempio potrebbe dichiarare variabili locali. Se avessimo un metodo di rilevamento delle collisioni, potrebbe sembrare qualcosa di simile:

boolean isCollidingWith(Entity entity) {
    return this.x < entity.x && this.x + this.width > entity.x || this.x > entity.x && entity.x + entity.width > this.x || ...;
}

Uno sviluppatore può volere ripulire dichiarando alcune variabili boolean locali:

boolean isCollidingWith(Entity entity) {
    boolean collideRight = this.x < entity.x && this.x + this.width > entity.x;
    boolean collideLeft = this.x > entity.x && entity.x + entity.width > this.x;

    return collideRight || collideLeft || ...;
}

Se uno dicesse " non hai bisogno di quelle variabili, semplicemente sprecano spazio ", sarebbe considerato mico-ottimizzazione. Anche se è possibile risparmiare un po 'di spazio, è trascurabile e il tentativo di salvare lo spazio potrebbe danneggiare la leggibilità.

Soddisfa le esigenze / i requisiti del tuo programma

You are required to write a program that calculates PI. Whoever writes the most powerful PI calculator wins a prize.

In uno scenario come questo, potresti preferire l'efficienza delle risorse rispetto alla leggibilità, conservando il più possibile. In seguito, prevedi di eliminare questo programma, quindi non dovrai più leggere questo codice.

Investirai ore per rendere scalabile questo progetto? Probabilmente no.

You own a popular social networking site.

Le regole sono cambiate. Hai milioni di utenti che richiedono costantemente contenuti, mentre tentano anche di correggere eventuali bug attualmente sfruttati. Oltre a questo, hai idee che vuoi implementare.

Le prestazioni sono importanti, ma ci sono molti altri fattori, potenzialmente più importanti, a portata di mano. La leggibilità è un must, a causa della necessità di un team e della necessità di rivisitare il codice.

Assicurati di aver compreso le esigenze della tua situazione.

Scopri come testare correttamente

Il test può essere un processo lungo e doloroso se non sai come farlo nel modo giusto. Potresti passare ore a litigare con i test, solo per capire che non hai testato correttamente un'unità.

Il test unitario è una forma di test tradizionale. Si concentra sul controllo dell'integrità di una singola unità di codice. Il test di integrazione sarebbe il prossimo passo: test nel suo complesso.

Mocking ti permette di ricreare situazioni che di solito non si verificano a comando, come vedere se un robot si sveglia quando scatta un allarme (potresti prendere in giro l'allarme e dargli uno specifico "tempo corrente", piuttosto che aspettare ).

Senza esporti a questi concetti, avrai difficoltà a garantire l'integrità del tuo software.

    
risposta data 13.02.2017 - 00:59
fonte
-2

È un compromesso. Dovresti ottimizzare quando c'è un probabile o chiaro vantaggio potenziale dall'ottimizzazione del codice e smettere di ottimizzarlo quando non ritieni più che il beneficio valga il tuo tempo.

Il costo, come hai detto, può essere frustrante, più tempo per trovare e correggere bug oscuri, creare test più approfonditi, documentare chiaramente i refactoring oscuri, rinunciare e ritirarsi a una versione precedente, ecc.

I vantaggi possono essere un po 'come imparare da come scrivere (o non scrivere!) codice "stretto" efficiente per situazioni successive in cui è richiesto (piccolo IoT incorporato, o zillion di costose istanze AWS, o rete dello spazio profondo caricamenti, durata della batteria dell'utente mobile ed ecc.)

In altre situazioni, la rimozione di codice duplicato potrebbe anche causare svantaggi (leggibilità del codice tutorial, rischi di cache / pipeline del processore e ecc.)

    
risposta data 13.02.2017 - 00:12
fonte

Leggi altre domande sui tag