Sembra che tu stia facendo due domande piuttosto diverse:
- Java è davvero lento, e se sì perché?
- Perché Java è percepito come lento, anche se è più veloce di molte alternative?
Il primo di questi è più o meno un tipo di domanda "quanto è lunga una corda". Dipende dalla tua definizione di "lento". Rispetto a un interprete puro, Java è estremamente veloce. Rispetto ad altre lingue che sono (normalmente) compilate in una sorta di bytecode, quindi compilate dinamicamente in codice macchina (es. C # o qualsiasi altra cosa su .NET) Java è approssimativamente alla pari. Rispetto ai linguaggi che sono normalmente compilati al puro codice macchina, e hanno (spesso grandi) team di persone che non lavorano altro che migliorare i loro ottimizzatori (ad esempio C, C ++, Fortran, Ada) Java fa abbastanza bene in alcune cose, ma nel complesso tende ad essere almeno un po 'più lento.
Gran parte di questo è legato principalmente all'implementazione - fondamentalmente, si riduce al fatto che un utente è in attesa mentre è in esecuzione un compilatore dinamico / JIT, quindi a meno che tu non abbia un programma che gira da un po 'per iniziare, è difficile giustificare il fatto che il compilatore impieghi molto tempo su difficili ottimizzazioni. Pertanto, la maggior parte dei compilatori Java (e C #, ecc.) Non si impegna molto in ottimizzazioni davvero difficili. In molti casi, è meno su ciò che le ottimizzazioni vengono eseguite, rispetto a dove vengono applicate. Molti problemi di ottimizzazione sono NP completi, quindi il tempo necessario aumenta rapidamente con l'attacco delle dimensioni del problema. Un modo per mantenere il tempo entro limiti ragionevoli è applicare l'ottimizzazione a qualcosa come una singola funzione alla volta. Quando è solo lo sviluppatore in attesa del compilatore, puoi permetterti di impiegare molto più tempo e applicare la stessa ottimizzazione a blocchi molto più grandi del programma. Allo stesso modo, il codice per alcune ottimizzazioni è piuttosto peloso (e quindi può essere piuttosto grande). Ancora una volta, poiché l'utente sta aspettando il caricamento di quel codice (e il tempo di avvio di JVM è spesso un fattore significativo nel tempo complessivo), l'implementazione deve bilanciare il tempo risparmiato in un posto rispetto a quello perso in un altro - e dato quanto poco codice beneficia delle ottimizzazioni pelose, mantenere di piccole dimensioni la JVM è generalmente più vantaggioso.
Un secondo problema è che con Java si ottiene spesso una soluzione più o meno "a misura unica". Ad esempio, per molti sviluppatori Java Swing è essenzialmente l' unica libreria di finestre disponibile. In qualcosa come C ++, ci sono letteralmente dozzine di librerie di finestre, framework di applicazioni, ecc. Ognuno con il proprio set di compromessi tra facilità d'uso vs. esecuzione veloce, aspetto coerente vs aspetto nativo e così via. L'unico vero punto critico è che alcuni (ad es. Qt) possono essere piuttosto costosi (almeno per uso commerciale).
Terzo, un sacco di codice scritto in C ++ (e C ancora di più) è semplicemente più vecchio e più maturo. In gran parte contiene un nucleo di routine scritte decenni fa, quando passare del tempo in più per ottimizzare il codice era un comportamento normale, previsto. Ciò ha spesso un reale vantaggio nel codice più piccolo e più veloce. C ++ (o C) ottiene il merito che il codice è piccolo e veloce, ma è molto più un prodotto dello sviluppatore e i vincoli del tempo in cui il codice è stato scritto. In una certa misura, questo porta a una profezia che si autoavvera: quando le persone si preoccupano della velocità, spesso scelgono C ++ perché ha quella reputazione. Hanno dedicato ulteriore tempo e sforzi all'ottimizzazione e viene scritta una nuova generazione di codice C ++ veloce.
Riassumendo, la normale implementazione di Java rende al massimo problematica la massima ottimizzazione. Peggio ancora, dove Java è visibile , cose come i toolkit per finestre e il tempo di avvio di JVM spesso svolgono un ruolo maggiore della velocità di esecuzione del linguaggio stesso. In molti casi, C e C ++ ottengono anche credito per ciò che è veramente il prodotto del semplice lavorare di più per l'ottimizzazione.
Per quanto riguarda la seconda domanda, penso che sia in gran parte una questione di natura umana al lavoro. Alcuni fanatici fanno affermazioni piuttosto gonfie sul fatto che Java sia accecantemente veloce. Qualcuno lo prova e scopre che anche un programma banale impiega alcuni secondi per iniziare e si sente lento e goffo quando funziona. Pochi probabilmente si preoccupano di analizzare le cose per rendersi conto che gran parte di questo è il tempo di avvio della JVM e il fatto che quando provano le cose per la prima volta, nessuno del codice è stato ancora compilato - parte del codice viene interpretato, e alcuni vengono compilati mentre aspettano. Peggio ancora, anche quando corre abbastanza veloce, l'aspetto e la sensazione di solito sembrano estranei e goffi per la maggior parte degli utenti, quindi anche se le misurazioni obiettive mostrassero tempi di risposta rapidi, sembrerebbe comunque goffo.
L'aggiunta di questi insieme porta a una reazione abbastanza semplice e naturale: Java è lento, brutto e goffo. Dato l'hype che dice che è davvero veloce, c'è una tendenza a reagire in modo eccessivo e concludere a pensarlo orribilmente lento, invece di un (più accurato) "leggermente più lento, e questo principalmente in circostanze specifiche". Questo è generalmente il peggiore per uno sviluppatore che scrive i primi programmi nella lingua. L'esecuzione di un programma "ciao mondo" nella maggior parte delle lingue appare istantanea, ma in Java c'è una pausa facilmente percettibile all'avvio della JVM. Anche un puro interprete che gira molto più lentamente su loop stretti e che apparirà spesso più veloce per codice come questo, semplicemente perché può essere caricato e iniziare a eseguire un po 'prima.