Non c'è una risposta a questo, in gran parte perché non è sempre vero. In realtà, probabilmente non è mai vero. Non puoi misurare la velocità di un linguaggio, ma solo la velocità di qualche particolare implementazione (e raramente persino l'implementazione nel suo complesso, solo della sua velocità di esecuzione su qualche particolare pezzo di codice.
Il codice Java può essere più lento del codice C ++, a volte di un fattore molto più grande di 2 o 3.
Il codice Java può anche essere competitivo con il codice C ++, ma spesso richiede molta più memoria per farlo.
Per alcuni, molto specifici, Java può essere più veloce del C ++ che è scritto in modo simile.
Detto questo, sì, in media il codice scritto in Java verrà eseguito più lentamente di (approssimativamente) codice equivalente scritto in C ++. Se la tua preoccupazione principale è con la velocità di esecuzione, Java ha un numero di svantaggi.
Il principale è che dipende molto da un compilatore JIT per l'ottimizzazione - ma poiché l'utente è in attesa mentre è in esecuzione il compilatore JIT, la maggior parte dei compilatori JIT non include le ottimizzazioni più costose. Dal momento che un compilatore C ++ funziona generalmente solo con uno sviluppatore in attesa (o nessuno in attesa, nel caso di build basate su server con sistemi CI e simili) è molto più ragionevole che il compilatore includa ogni ottimizzazione nel libro.
Un secondo fattore è strettamente correlato: i venditori C ++ considerano i propri clienti estremamente interessati alla velocità. I venditori di Java vedono quasi certamente i propri clienti come più interessati a cose come le caratteristiche e lo sviluppo veloce rispetto a raggiungere la massima velocità di esecuzione possibile. Questo non vuol dire che possano o non debbano trascurare completamente la velocità di esecuzione, solo che non lo enfatizzano quasi allo stesso livello dei venditori C ++.
Anche la raccolta dei dati inutili può avere un effetto. Java (normalmente) utilizza un programma di raccolta simultaneo e di copia. Funziona abbastanza bene su una vasta gamma di carichi di lavoro, e la maggior parte delle JVM ha alcune "manopole di sintonia" per aiutare quando le impostazioni predefinite non sono ottimali.
Tuttavia, i test sembrano indicare che una JVM richiede sostanzialmente più memoria di un equivalente codice C ++ per sperare di funzionare alla stessa velocità (approssimativamente). Soprattutto quando si esegue una situazione limitata alla memoria, il sovraccarico della raccolta dei dati obsoleti può aumentare notevolmente. Questo in genere deriva meno dalla frequenza con cui il garbage collector viene eseguito (di per sé), piuttosto che dal fatto che quando viene eseguito, molti oggetti sono ancora "vivi". Un collezionista di copie lavora copiando oggetti "dal vivo" (raggiungibili) in una nuova posizione, quindi idealmente vuoi che quasi tutti gli oggetti siano "morti" (irraggiungibili) prima di essere eseguiti. Con meno memoria, non solo viene eseguito più spesso, ma ogni iterazione richiede più tempo perché meno oggetti hanno abbastanza età per "morire" e più oggetti rimangono raggiungibili (e quindi devono essere copiati).
C'è anche una differenza nella quantità di lavoro che viene eseguita in fase di esecuzione rispetto al tempo di compilazione. C ++ pone molta enfasi sul fare il più possibile in fase di compilazione. Ad esempio, tutte le "cose" interessanti del modello si verificano interamente in fase di compilazione (a scapito di tempi di compilazione orribilmente lunghi in alcuni casi). Nonostante la sintassi simile, gran parte (la maggior parte?) Dell'applicazione dei tipi di Java nel suo sistema generico avviene in fase di esecuzione. Java include anche (e molti programmi Java usano) cose come la reflection, che semplicemente non sono presenti in C ++.
Java aggiunge anche una serie di funzioni di comodità come il box automatico che rendono abbastanza facile aggiungere un po 'di overhead a operazioni apparentemente semplici in modi che non sono immediatamente evidenti. Anche il C ++ ne ha alcuni, ma (sembra a me) sono entrambi in numero minore, e i loro effetti dannosi sono in genere meno drastici (ma la mia opinione su questo potrebbe essere influenzata dal fatto che conosco abbastanza C ++ un po 'meglio, quindi per me, problemi simili possono sembrare molto più ovvi in C ++ che in Java).
In conclusione: è difficile indicare un singolo motivo specifico per cui i programmi Java sono più lenti dei programmi C ++. Sebbene sia vero il più delle volte, le ragioni del suo accadere variano molto, e in molti casi sembra essere più la "morte di mille tagli" che essere il risultato di un singolo fattore.