J'espère que vous vous rendez compte que tout cela est profondément défini par l'implémentation, à la fois pour Java et C ++. Cela étant dit, le modèle objet de Java nécessite un peu d'espace.
Les objets C ++ n'ont (généralement) besoin d' aucun stockage sauf ceux dont les membres ont besoin. Notez que (contrairement à Java, où tout ce qui est défini par l'utilisateur est un type de référence), le code client peut utiliser un objet à la fois comme type de valeur ou comme type de référence, c'est-à-dire qu'un objet peut stocker un pointeur / référence vers un autre objet, ou stocker directement l'objet sans indirection. Un pointeur supplémentaire par objet est nécessaire s'il existe des virtual
méthodes, mais plusieurs classes utiles sont conçues pour s'entendre sans polymorphisme et n'en ont pas besoin. Il n'y a pas de métadonnées GC ni de verrouillage par objet. Ainsi, les class IntWrapper { int x; public: IntWrapper(int); ... };
objets n'ont pas besoin de plus d'espace que les int
s simples et peuvent être placés directement (c'est-à-dire sans indirection) dans les collections et autres objets.
Les tableaux sont délicats simplement parce qu'il n'y a pas d'équivalent prédéfini et commun à un tableau Java en C ++. Vous pouvez simplement allouer un tas d'objets avec new[]
(sans aucune surcharge / métadonnée) mais il n'y a pas de champ de longueur - l'implémentation en stocke probablement un mais vous ne pouvez pas y accéder. std::vector
est un tableau dynamique et a donc une surcharge supplémentaire et une interface plus grande. std::array
et les tableaux de style C (int arr[N];
), ont besoin d'une constante de temps de compilation. En théorie, cela devrait être juste le stockage de l'objet plus un seul entier pour la longueur - mais comme vous pouvez obtenir un redimensionnement dynamique et une interface complète avec très peu d'espace supplémentaire, vous optez simplement pour cela dans la pratique. Notez que tous ceux-ci, ainsi que toutes les autres collections, stockent par défaut les objets par valeur, vous économisant ainsi l'indirection et l'espace pour les références, et améliorant le comportement du cache. Vous devez explicitement stocker des pointeurs (intelligents, s'il vous plaît) pour obtenir l'indirection.
Les comparaisons ci-dessus ne sont pas entièrement justes, car certaines de ces économies sont réalisées en n'incluant pas les fonctionnalités incluses par Java, et leur équivalent C ++ est souvent moins optimisé que l'équivalent Java (*). La manière courante d'implémenter virtual
en C ++ impose exactement autant de frais généraux que la manière courante d'implémenter virtual
en Java. Pour obtenir un verrou, vous avez besoin d'un objet mutex complet, qui est probablement plus grand que quelques bits. Pour obtenir le comptage des références ( paséquivalent à GC, et ne doit pas être utilisé comme tel, mais parfois utile), vous avez besoin d'un pointeur intelligent qui ajoute un champ de comptage de référence. À moins que l'objet ne soit construit avec soin, le nombre de références, l'objet pointeur intelligent et l'objet référencé sont dans des emplacements complètement séparés, et même lorsque vous le construisez correctement, le pointeur partagé peut (doit?) Toujours être deux pointeurs au lieu d'un. Là encore, un bon style C ++ n'utilise pas suffisamment ces fonctionnalités pour que cela ait de l'importance - en pratique, les objets d'une bibliothèque C ++ bien écrits en utilisent moins. Cela ne signifie pas nécessairement moins d'utilisation de la mémoire dans l'ensemble, mais cela signifie que C ++ a une bonne longueur d'avance à cet égard.
(*) Par exemple, vous pouvez obtenir des appels virtuels, des codes de hachage d'identité et un verrouillage avec un seul mot pour certains objets (et deux mots pour de nombreux autres objets) en fusionnant les informations de type avec divers indicateurs et en supprimant les bits de verrouillage pour les objets qui sont peu susceptible d'avoir besoin de verrous. Voir Implémentation efficace en temps et en espace du modèle objet Java (PDF) par David F. Bacon, Stephen J. Fink et David Grove pour une explication détaillée de cette optimisation et d'autres.
int
? Si c'est le cas, vous devriez comparer cela àint
Java, pasInteger
- tant que vos entrées C ++ sont 32 bits.