• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Codemotion Magazine

We code the future. Together

  • Discover
    • Events
    • Community
    • Partners
    • Become a partner
    • Hackathons
  • Magazine
    • Backend
    • Dev community
    • Carriere tech
    • Intelligenza artificiale
    • Interviste
    • Frontend
    • DevOps/Cloud
    • Linguaggi di programmazione
    • Soft Skill
  • Talent
    • Discover Talent
    • Jobs
    • Manifesto
  • Companies
  • For Business
    • EN
    • IT
    • ES
  • Sign in
ads

peduz91Luglio 22, 2024

Ottimizzazione delle prestazioni in Java: guida pratica

Backend
ottimizzazione java guida
facebooktwitterlinkedinreddit

La considerazione sulle prestazioni è fondamentale per sviluppare applicazioni efficienti, scalabili e reattive, garantire che le applicazioni utilizzino al meglio le risorse di sistema, come memoria e CPU, è essenziale per migliorare l’esperienza utente, ridurre i costi operativi e mantenere un vantaggio competitivo.

In questo articolo analizzeremo il problema delle performance con dei riferimenti e con esempi di codice in java.

Recommended article
Giugno 3, 2025

La signature chain: garanzia di autenticità, integrità e sequenzialità nei documenti digitali

Antonio Musarra

Backend

Sfide prestazionali

Le applicazioni devono affrontare diverse sfide prestazionali:

  • Tempo di risposta lento: impatta negativamente l’esperienza utente.
  • Utilizzo inefficiente della memoria: può causare eccezioni OutOfMemoryError e aumentare la latenza.
  • Carico eccessivo della CPU: rallenta il sistema e riduce la scalabilità.
  • Accesso lento al database: può diventare un collo di bottiglia se non ottimizzato.

Tecniche di ottimizzazione

Profilazione del codice

La profilazione del codice aiuta a identificare le parti del codice che richiedono ottimizzazione, strumenti come Java VisualVM, JProfiler e YourKit Java Profiler sono utili per analizzare l’utilizzo della CPU, la memoria e altre risorse.
Vediamo un esempio di codice con delle istruzioni di come profilarlo con VisualVM:

public class ProfilazioneEsempio {

    public static void main(String[] args) {
        ProfilazioneEsempio esempio = new ProfilazioneEsempio();
        esempio.calcoloComplesso();
    }

    // Metodo complesso che vogliamo profilare
    public void calcoloComplesso() {
        long total = 0;
        for (int i = 0; i < 10000; i++) {
            total += Math.pow(i, 2);
            try {
                Thread.sleep(1); // Simulazione di un ritardo
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Risultato: " + total);
    }
}
Code language: JavaScript (javascript)

Profilazione con VisualVM

  1. Preparazione dell’Ambiente:
    • Compila ed esegui il programma Java.
  2. Avvio di VisualVM:
    • Avvia VisualVM.
    • Dovresti vedere la tua applicazione Java in esecuzione sotto la sezione “Applications”.
  3. Attivazione della Profilazione:
    • Seleziona l’applicazione Java dalla lista delle applicazioni.
    • Vai alla scheda “Profiler”.
    • Clicca su “CPU” per avviare la profilazione della CPU.
  4. Esecuzione del Codice Profilato:
    • VisualVM inizierà a raccogliere dati sulle prestazioni del metodo calcoloComplesso.
    • Lascia che il programma termini l’esecuzione per raccogliere un profilo completo.
  5. Analisi dei Risultati:
    • Una volta terminata l’esecuzione, VisualVM mostrerà i risultati della profilazione.
    • Identifica i metodi che consumano più tempo. Nel nostro esempio, dovresti vedere che il metodo calcoloComplesso e Thread.sleep sono tra i principali consumatori di tempo.

VisualVM mostrerà un’analisi dettagliata del tempo trascorso in ciascun metodo. Puoi usare queste informazioni per ottimizzare il tuo codice, ad esempio riducendo il tempo di attesa o migliorando l’algoritmo di calcolo.

Consigli sulle prestazioni in Java: uso di StringBuilder vs. String

Quando si sviluppa in Java, è fondamentale considerare le prestazioni del codice, soprattutto quando si tratta di operazioni ripetitive o intensive. Un esempio classico di ottimizzazione riguarda la concatenazione delle stringhe. In Java, le stringhe (String) sono immutabili, il che significa che ogni volta che si modifica una stringa, viene creata una nuova istanza di String. Questo può portare a inefficienze significative quando si concatenano molte stringhe in un ciclo. Utilizzare StringBuilder invece di String per queste operazioni può migliorare notevolmente le prestazioni.

Esempio di concatenazione delle stringhe

Consideriamo due approcci per concatenare stringhe in un ciclo: uno che utilizza String e uno che utilizza StringBuilder.

Utilizzo di String:

public class StringConcatenation {

    public static void main(String[] args) {
        String result = "";
        for (int i = 0; i < 10000; i++) {
            result += i;
        }
        System.out.println(result.length());
    }
}Code language: JavaScript (javascript)

Utilizzo di StringBuilder:

public class StringBuilderConcatenation {

    public static void main(String[] args) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            result.append(i);
        }
        System.out.println(result.length());
    }
}Code language: JavaScript (javascript)

Perché StringBuilder è più Efficiente di String?

  1. Immutabilità di String:
    • Ogni volta che una stringa viene modificata, viene creata una nuova istanza di String.
    • Questo comporta un overhead di memoria e CPU perché crea nuovi oggetti e necessita di copiare i contenuti esistenti.
  2. Mutable Buffer di StringBuilder:
    • StringBuilder utilizza un buffer mutabile che può essere modificato senza creare nuovi oggetti.
    • Quando concateniamo nuove stringhe, StringBuilder semplicemente modifica il buffer esistente, il che è molto più efficiente.
  3. Performance:
    • L’approccio con String risulta in O(n^2) operazioni per la concatenazione, dove n è il numero di concatenazioni, a causa della necessità di copiare ripetutamente le stringhe esistenti.
    • L’approccio con StringBuilder è O(n) perché aggiunge semplicemente le nuove stringhe al buffer.

Esempio di Profilazione delle Prestazioni

Utilizziamo un semplice test di tempo per confrontare i due approcci:

public class PerformanceTest {

    public static void main(String[] args) {
        long startTime, endTime;

        // Test con String
        startTime = System.nanoTime();
        String result = "";
        for (int i = 0; i < 10000; i++) {
            result += i;
        }
        endTime = System.nanoTime();
        System.out.println("Tempo con String: " + (endTime - startTime) + " ns");

        // Test con StringBuilder
        startTime = System.nanoTime();
        StringBuilder sbResult = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            sbResult.append(i);
        }
        endTime = System.nanoTime();
        System.out.println("Tempo con StringBuilder: " + (endTime - startTime) + " ns");
    }
}Code language: JavaScript (javascript)

Nella maggior parte dei casi, vedrai che il tempo di esecuzione utilizzando StringBuilder è significativamente inferiore rispetto a quello con String. Questo semplice esempio dimostra l’importanza di scegliere gli strumenti giusti per le operazioni specifiche in Java, il punto è che capire e scegliere gli strumenti appropriati messi a disposizione dal linguaggio e dalle librerie è cruciale per scrivere codice efficiente. L’uso di StringBuilder per la concatenazione di stringhe è solo uno degli esempi. Altri includono l’utilizzo di collezioni adeguate (ArrayList vs LinkedList), tecniche di caching, e l’uso di stream paralleli per il calcolo distribuito. Profilare e comprendere le caratteristiche delle diverse strutture dati e metodologie può fare una grande differenza nelle prestazioni delle applicazioni.

Articolo consigliato: evitare gli “Smell Patterns” in Java

Strumenti di profilazione

Di seguito facciamo una carrellata degli strumenti più utilizzati per la profilazione delle applicazioni java (ciascuno con le sue caratteristiche e particolarità). Qualcuno di questi è a pagamento e la loro scelta va fatta a seconda di ciò che è più funzionale per il progetto.

Java VisualVM

VisualVM è uno strumento visuale che integra strumenti JDK da riga di comando e funzionalità di profiling, progettato per l’uso sia in fase di sviluppo che di produzione.

JProfiler

Strumento commerciale con funzionalità avanzate per l’analisi delle prestazioni, supportando diverse piattaforme e integrazioni.

YourKit Java Profiler

Offre strumenti avanzati per l’analisi delle prestazioni di applicazioni Java SE, Java EE e Android.

Eclipse MAT

Strumento open source per l’analisi della memoria, utile per identificare fughe di memoria e ottimizzare l’utilizzo della memoria.

Consigli per ottimizzare il codice Java

  • Evitare l’uso di metodi deprecati.
  • Minimizzare le conversioni di tipo.
  • Utilizzare correttamente le collezioni.
  • Limitare l’uso di chiamate di metodo ricorsive.
  • Utilizzare equals() per confronti di oggetti.
  • Evitare la concatenazione di stringhe in loop.
  • Utilizzare il caching quando appropriato.
  • Minimizzare l’uso di blocchi sincronizzati.
  • Minimizzare l’uso di I/O sincrono.

Conclusione

Ottimizzare le prestazioni in Java richiede un’attenta selezione degli strumenti e delle tecniche disponibili. Scegliere la soluzione più efficiente, come l’uso di StringBuilder per la concatenazione di stringhe, può fare una grande differenza. Profilare il codice, monitorare le prestazioni e iterare costantemente sono pratiche essenziali per sviluppare applicazioni rapide e efficienti. Investire tempo nel comprendere le peculiarità delle librerie e delle strutture dati non solo migliora la velocità del codice, ma contribuisce anche alla sua scalabilità e manutenibilità nel lungo termine.

Codemotion Collection Background
Guide Codemotion
Selezionati per te

Vuoi scoprire più articoli come questo? Dai un’occhiata alla collection Guide Codemotion dove troverai sempre nuovi contenuti selezionati dal nostro team.

Share on:facebooktwitterlinkedinreddit

Tagged as:Java ottimizzazione

peduz91
Sono uno sviluppatore software con forte passione per lo sviluppo, la tecnologia, il calcio e gli scacchi. Mi piace mettermi sempre in gioco, provo spesso cose nuove. Credo che la cosa più importante sia lavorare bene con il team.
Luca Mezzalira keynote a Codemotion Milano 2024!
Previous Post
Le API di Bruno – Assertion e Test
Next Post

Footer

Discover

  • Events
  • Community
  • Partners
  • Become a partner
  • Hackathons

Magazine

  • Tech articles

Talent

  • Discover talent
  • Jobs

Companies

  • Discover companies

For Business

  • Codemotion for companies

About

  • About us
  • Become a contributor
  • Work with us
  • Contact us

Follow Us

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions