Performance
Otimização
Engenharia de Software
Observabilidade
Boas Práticas

Prestazioni del software: i passaggi essenziali per iniziare a ottimizzare

L'ottimizzazione delle prestazioni ha ordine. Saltare la diagnosi è l’errore più comune e più costoso.

Quando un'applicazione rallenta, l'istinto della maggior parte dei team è quello di iniziare ad armeggiare. Cambia una libreria, aggiungi una cache, aggiorna una macchina più grande. È la reazione sbagliata, ed è costosa, perché attacca i sintomi prima di comprendere la malattia.

La performance ha un metodo. Esiste un giusto ordine di passaggi e inizia molto prima di toccare una riga di codice. Questo articolo è per chi ha già capito che bisogna ottimizzare e vuole sapere da dove cominciare in modo disciplinato, senza perdere settimane nel posto sbagliato.

Non lo tratterò come un elenco di trucchi. I trucchi risolvono casi specifici e invecchiano rapidamente. Il metodo risolve ogni caso e si sostiene da solo.

Passaggio 0: definisci cosa significa "veloce".

Prima di tutto, rispondi: cosa è accettabile? "Il sistema è lento" non è un problema risolvibile. "La pagina dell'elenco deve rispondere in meno di un secondo per il 95% delle richieste" lo è.

Senza un obiettivo non sai mai quando fermarti. L'ottimizzazione senza un obiettivo è un buco senza fondo, puoi sempre realizzarla più velocemente e ottenere di meno costa sempre più impegno. Definire limiti di tempo di risposta accettabili, idealmente per percentile, trasforma una sensazione diffusa in un criterio oggettivo.

Questo passaggio sembra burocratico, ma è ciò che separa uno sforzo di ottimizzazione da una caccia senza fine. Ed è una conversazione di prodotto e di business tanto quanto di ingegneria: ciò che è "abbastanza veloce" dipende da ciò che l'utente sta cercando di fare.

Passaggio 1: misurare prima dello spostamento

La regola più importante di tutta questa disciplina: non ottimizzi ciò che non misuri. Senza strumentazione, qualsiasi cambiamento è una supposizione, e le supposizioni avvengono per fortuna.

Dotare l'applicazione di metriche, log strutturati e, idealmente, tracciamento distribuito. L’obiettivo è rispondere a una semplice domanda: dove viene speso il tempo? La risposta sorprende quasi sempre. Raramente il collo di bottiglia si trova dove l’intuito lo segnala.

Uno schema ricorrente: il team giura che il problema è il linguaggio o il framework, gli strumenti, e scopre che l'80% delle volte è in una singola query del database. Senza la misurazione, questo team avrebbe riscritto l’intera applicazione e il problema sarebbe ancora presente.

Lo strumento conta meno dell’abitudine. Potrebbe essere una soluzione completa di osservabilità o un registro ben posizionato. Ciò che non può mancare sono i dati.

Passo 2: Attacca per primo il collo di bottiglia più grande

Con i dati in mano, la definizione delle priorità diventa ovvia. Esiste una potente regola empirica: la maggior parte dei rallentamenti tende a derivare da una minoranza di cause. Attacca prima quello più grande.

Resisti alla tentazione di fare dieci micro-ottimizzazioni che si sommano a poco. Trova l'elemento che da solo richiede la maggior parte del tempo e risolvilo. Il guadagno derivante dall’eliminazione del collo di bottiglia principale è solitamente maggiore di quello derivante da tutti gli altri miglioramenti messi insieme.

Dopo aver determinato il valore più grande, misurare nuovamente. Il collo di bottiglia si è spostato. Il secondo più grande è ora il nuovo obiettivo. La performance è un processo iterativo di misurazione, correzione e riparazione, non un singolo sforzo.

Passaggio 3: inizia con il database

Nella maggior parte delle applicazioni aziendali, il settore bancario è il luogo in cui si spreca la maggior parte del tempo. Ecco perché merita un'attenzione prioritaria. Tre controlli risolvono un'enorme frazione di problemi:

  • Indici mancanti. Query che eseguono la scansione dell'intera tabella perché manca un indice nella colonna filtrata. È l’errore più comune e il più economico da correggere.
  • Il problema N+1. Quando il codice esegue una query per l'elenco e quindi un'ulteriore query per ciascun elemento nell'elenco. Cento elementi hanno ricevuto centouno query. Si risolve caricando immediatamente i dati correlati.
  • Query che contengono troppi dati. La ricerca nell'intera tabella per utilizzare tre colonne è uno spreco di database, rete e memoria.

Queste tre soluzioni da sole trasformano la percezione della velocità per molti sistemi. E nessuno di essi richiede un cambiamento tecnologico.

Passaggio 4: utilizza la cache in modo saggio

La cache è l'ottimizzazione più seducente e più pericolosa. Offre vantaggi immediati e introduce un'intera classe di nuovi bug: dati obsoleti.

La regola d'oro: arricciare solo ciò che può essere leggermente vecchio senza causare danni. E definire sempre esplicitamente come verrà invalidata la cache. La cache senza una strategia di invalidazione non è ottimizzazione, è una bomba a orologeria.

Per dati sensibili, saldi, stato degli ordini, informazioni che cambiano e la cui accuratezza conta, pensaci due volte. Nei sistemi che si occupano di denaro o di decisioni dei cittadini, la correttezza dei dati vince sulla velocità. Mostrare un numero sbagliato più velocemente non aiuta nessuno.

Vale anche la pena ricordare che la cache esiste su più livelli: nel browser dell'utente, in uno strato intermedio, sul server, in banca. Ciascuno risolve un problema diverso e ha il proprio costo di invalidazione. L'errore del principiante è quello di impilare le cache senza capire quale risponde a cosa, e poi, quando un dato va storto, nessuno sa in quale livello è rimasto bloccato. Mappare consapevolmente dove opera la cache fa parte del suo buon utilizzo.

Step 5: solo dopo pensare alle infrastrutture

L'aggiornamento di una macchina più grande o l'aggiunta di più istanze è spesso il primo passo compiuto dai team. Dovrebbe essere uno degli ultimi.

Il ridimensionamento dell’infrastruttura senza prima correggere il codice e i colli di bottiglia del settore bancario sta gettando denaro sul problema. Paghi di più per svolgere lo stesso lavoro inefficiente, solo in parallelo. I costi crescono e l’inefficienza è ancora lì, ora più cara.

Quando l'ottimizzazione del codice è già stata eseguita e il vero limite è la capacità, allora entra in gioco l'infrastruttura. E il modo giusto è quasi sempre scalare orizzontalmente, aggiungere istanze, il che richiede che l'applicazione sia stateless. Si tratta di una decisione architetturale che vale la pena prendere presto, perché risolverla in un secondo momento è laboriosa.

L'errore che invalida tutti i passaggi

C’è un difetto culturale che sabota qualsiasi copione: ottimizzare attraverso l’intuizione e celebrare senza misurare il risultato. La squadra cambia qualcosa, sente di essere diventata più veloce e va avanti. Senza misurazione dopo il cambiamento, non puoi sapere se è migliorato, peggiorato o se non è successo nulla.

Ogni ottimizzazione necessita di un prima e di un dopo misurabili. Altrimenti stai semplicemente spostando il codice e torcendolo.

La riflessione onesta: la maggior parte dei problemi di prestazione non richiedono geni o strumenti costosi. Richiede disciplina. Misurare, stabilire le priorità, risolvere il collo di bottiglia più grande, rimediare. Le squadre che seguono questo ordine risolvono in giorni ciò che le squadre che indovinano non possono risolvere in mesi.

Le prestazioni eseguite bene riguardano meno il talento e più il processo. Coloro che interiorizzano questi passaggi smettono di spegnere gli incendi e iniziano a prevenirli.

Se il tuo team continua a risolvere la lentezza nel buio, forse il problema non è tecnico, ma metodologico. Ci sono altri articoli sul blog su qualità, osservabilità e scalabilità che completano questa tabella di marcia. Se vuoi scambiare idee su come strutturarlo nella tua organizzazione, vale la pena parlarne.

Leggi anche