Spero che ti renda conto che tutto ciò è profondamente definito dall'implementazione, sia per Java che per C ++. Detto questo, il modello a oggetti di Java richiede un po 'di spazio.
Oggetti C ++ non lo fanno (in genere) hanno bisogno di alcuna archiviazione, tranne ciò che i membri hanno bisogno. Si noti che (a differenza di Java, dove tutto definito dall'utente è un tipo di riferimento), il codice client può utilizzare un oggetto sia come tipo di valore che come tipo di riferimento, ovvero un oggetto potrebbe memorizzare un puntatore / riferimento a un altro oggetto o archiviare l'oggetto direttamente senza riferimento indiretto. Un puntatore aggiuntivo per oggetto è necessario se ci sono virtual
metodi, ma alcune classi utili sono progettate per andare d'accordo senza polimorfismo e non ne hanno bisogno. Non ci sono metadati GC e nessun blocco per oggetto. Pertanto gli class IntWrapper { int x; public: IntWrapper(int); ... };
oggetti non hanno bisogno di più spazio delle semplici int
e possono essere posizionati direttamente (cioè senza riferimento indiretto) in raccolte e altri oggetti.
Le matrici sono complicate semplicemente perché non esiste un equivalente comune prefabbricato di una matrice Java in C ++. Potresti semplicemente allocare un gruppo di oggetti con new[]
(senza assolutamente overhead / metadata) ma non c'è un campo di lunghezza - l'implementazione probabilmente ne memorizza uno ma non puoi accedervi. std::vector
è un array dinamico e quindi ha un sovraccarico aggiuntivo e un'interfaccia più grande. std::array
e array in stile C (int arr[N];
), è necessaria una costante di compilazione. In teoria, dovrebbe essere solo l'archiviazione dell'oggetto più un singolo intero per la lunghezza, ma poiché è possibile ottenere il ridimensionamento dinamico e un'interfaccia completa con pochissimo spazio aggiuntivo, in pratica lo si fa. Si noti che tutti questi, così come tutte le altre raccolte, per impostazione predefinita memorizzano gli oggetti in base al valore, risparmiando in tal modo indiretta e spazio per i riferimenti e migliorando il comportamento della cache. È necessario memorizzare esplicitamente i puntatori (quelli intelligenti, per favore) per ottenere l'indirizzamento indiretto.
I confronti di cui sopra non sono del tutto equi, poiché alcuni di questi risparmi sono offerti non includendo le funzionalità incluse in Java e il loro equivalente C ++ è spesso meno ottimizzato dell'equivalente Java (*). Il modo comune di implementare virtual
in C ++ impone esattamente tanto overhead quanto il modo comune di implementare virtual
in Java. Per ottenere un blocco, hai bisogno di un oggetto mutex con funzionalità complete, che molto probabilmente è più grande di qualche bit. Per ottenere il conteggio dei riferimenti ( noequivalente a GC, e non dovrebbe essere usato come tale, ma a volte utile), è necessario un puntatore intelligente che aggiunge un campo di conteggio dei riferimenti. A meno che l'oggetto non sia stato costruito con cura, il conteggio dei riferimenti, l'oggetto puntatore intelligente e l'oggetto referenziato si trovano in posizioni completamente separate e anche quando lo si costruisce nel modo giusto, il puntatore condiviso può (deve?) Essere ancora due puntatori anziché uno. Inoltre, il buon stile C ++ non utilizza queste funzionalità abbastanza per essere importante: in pratica, gli oggetti di una libreria C ++ ben scritta ne usano meno. Ciò non significa necessariamente un minore utilizzo complessivo della memoria, ma significa che C ++ ha un buon vantaggio in questo senso.
(*) Ad esempio, è possibile ottenere chiamate virtuali, codici hash di identità e blocco con una sola parola per alcuni oggetti (e due parole per molti altri oggetti) unendo le informazioni sul tipo con vari flag e rimuovendo i bit di blocco per gli oggetti che sono difficilmente avrà bisogno di serrature. Vedi l' implementazione efficiente in termini di spazio e tempo del modello a oggetti Java (PDF) di David F. Bacon, Stephen J. Fink e David Grove per una spiegazione dettagliata di questa e altre ottimizzazioni.
int
? In tal caso, dovresti confrontarlo conint
in Java, nonInteger
- purché i tuoi C ++ siano 32 bit.