java type - Pourquoi l'API Java utilise int au lieu de short ou byte?




3 Answers

Certaines des raisons ont déjà été soulignées. Par exemple, le fait que "... (Presque) Toutes les opérations sur octet, court va promouvoir ces primitives à int" . Cependant, la prochaine question évidente serait: POURQUOI ces types sont-ils promus à int ?

Donc, pour approfondir un niveau: La réponse peut simplement être liée au Java Virtual Machine Instruction Set. Comme résumé dans le tableau dans la spécification Java Virtual Machine , toutes les opérations arithmétiques intégrales, comme l'ajout, la division et d'autres, ne sont disponibles que pour le type int et le type long , et non pour les types plus petits.

(Un aparté: Les plus petits types ( byte et short ) ne sont fondamentalement destinés qu'aux tableaux : un tableau comme new byte[1000] prendra 1000 bytes, et un tableau comme new int[1000] prendra 4000 bytes)

Maintenant, bien sûr, on pourrait dire que "... la prochaine question évidente serait: POURQUOI ces instructions sont-elles seulement offertes pour int (et long )?" .

Une raison est mentionnée dans la spécification JVM mentionnée ci-dessus:

Si chaque instruction typée prenait en charge tous les types de données d'exécution de la machine virtuelle Java, il y aurait plus d'instructions que ce qui pourrait être représenté dans un octet.

De plus, la machine virtuelle Java peut être considérée comme une abstraction d'un vrai processeur. Et l'introduction d'une unité logique arithmétique dédiée pour des types plus petits ne vaudrait pas la peine: elle aurait besoin de transistors supplémentaires, mais elle ne pourrait toujours exécuter qu'une seule addition dans un cycle d'horloge. L'architecture dominante lors de la conception de la JVM était de 32 bits, juste pour un int 32 bits. (Les opérations qui impliquent une valeur de 64 bits sont implémentées dans un cas particulier).

(Remarque: Le dernier paragraphe est un peu trop simplifié, en considérant la vectorisation possible, etc., mais devrait donner l'idée de base sans plonger trop profondément dans les sujets de conception de processeurs)

EDIT: Un petit addendum, centré sur l'exemple de la question, mais dans un sens plus général: On pourrait aussi se demander s'il ne serait pas avantageux de stocker des champs en utilisant les plus petits types. Par exemple, on pourrait penser que la mémoire pourrait être sauvegardée en enregistrant Calendar.DAY_OF_WEEK comme un byte . Mais ici, le Java Class File Format entre en jeu: Tous les champs d'un fichier de classe occupent au moins un "slot", qui a la taille d'un int (32 bits). (Les champs "larges", double et long , occupent deux fentes). Ainsi, déclarer explicitement qu'un champ est short ou byte ne sauverait pas de mémoire non plus.

variable long

Pourquoi l'API Java utilise-t-elle int , alors que short ou byte suffirait?

Exemple: Le champ DAY_OF_WEEK de la classe Calendar utilise int .

Si la différence est trop minime, alors pourquoi ces types de données ( short , int ) existent-ils?




Parce que les opérations arithmétiques sont plus faciles lors de l'utilisation d'entiers par rapport aux courts métrages. Supposons que les constantes ont bien été modélisées par short valeurs short . Ensuite, vous devrez utiliser l'API de cette manière:

short month = Calendar.JUNE;
month = month + (short) 1; // is july

Notez le casting explicite. Les valeurs courtes sont implicitement promues à des valeurs int lorsqu'elles sont utilisées dans des opérations arithmétiques. (Sur la pile d'opérandes, les courts-circuits sont même exprimés sous forme d'ints.) Ce serait assez compliqué à utiliser, c'est pourquoi les valeurs int sont souvent préférées pour les constantes.

Par rapport à cela, le gain en efficacité de stockage est minime car il n'existe qu'un nombre fixe de telles constantes. Nous parlons de 40 constantes. En changeant leur stockage d' int à short , vous serez en sécurité 40 * 16 bit = 80 byte . Voir cette réponse pour plus de référence.




La complexité de conception d'une machine virtuelle est fonction du nombre de types d'opérations qu'elle peut effectuer. Il est plus facile d'avoir quatre implémentations d'une instruction comme "multiplier" - une pour chaque entier 32 bits, un entier 64 bits, un flottant 32 bits et un point flottant 64 bits - que d'avoir, en plus à ce qui précède, les versions pour les types numériques plus petits aussi bien. Une question de conception plus intéressante est pourquoi il devrait y avoir quatre types, plutôt que moins (effectuer tous les calculs entiers avec des entiers 64 bits et / ou faire tous les calculs à virgule flottante avec des valeurs à virgule flottante de 64 bits). La raison de l'utilisation d'entiers 32 bits est que Java devait fonctionner sur de nombreuses plates-formes où les types 32 bits pouvaient être traités aussi rapidement que les types 16 bits ou 8 bits, mais les opérations sur les types 64 bits seraient notablement Ralentissez. Même sur les plates-formes où les types 16 bits seraient plus rapides à travailler, le coût supplémentaire de travailler avec des quantités de 32 bits serait compensé par la simplicité offerte par les types 32 bits seulement.

Quant à l'exécution de calculs à virgule flottante sur des valeurs de 32 bits, les avantages sont un peu moins clairs. Il y a quelques plates-formes où un calcul comme float a=b+c+d; Cela peut être effectué plus rapidement en convertissant tous les opérandes en un type de précision supérieure, en les ajoutant, puis en convertissant le résultat en un nombre à virgule flottante de 32 bits pour le stockage. Il existe d'autres plateformes où il serait plus efficace d'effectuer tous les calculs en utilisant des valeurs à virgule flottante de 32 bits. Les créateurs de Java ont décidé que toutes les plateformes devraient être obligées de faire les choses de la même manière, et qu'elles devraient privilégier les plates-formes matérielles pour lesquelles les calculs en virgule flottante 32 bits sont plus rapides que les plus longs. et la précision des calculs en virgule flottante sur un PC typique, ainsi que sur de nombreuses machines sans unités à virgule flottante. Notez, btw, qu'en fonction des valeurs de b, c et d, en utilisant des calculs intermédiaires de plus haute précision lors du calcul d'expressions comme le float a=b+c+d; ci-dessus float a=b+c+d; produira parfois des résultats qui sont significativement plus précis que ce qui serait obtenu de tous les opérandes intermédiaires ont été calculés à la précision du float , mais donnera parfois une valeur qui est un peu moins précise. Quoi qu'il en soit, Sun a décidé que tout devrait être fait de la même manière, et ils ont opté pour l'utilisation de valeurs float précision minimale.

Notez que les avantages principaux des types de données plus petits deviennent évidents lorsqu'un grand nombre d'entre eux sont stockés ensemble dans un tableau; même s'il n'y avait aucun avantage à avoir des variables individuelles de types inférieurs à 64 bits, il vaut la peine d'avoir des tableaux qui peuvent stocker des valeurs plus petites de manière plus compacte; avoir une variable locale est un byte plutôt qu'un long enregistre sept octets; avoir un tableau de 1.000.000 nombres tenir chaque nombre comme un byte plutôt que de long vagues 7 000 000 octets. Étant donné que chaque type de tableau ne nécessite que quelques opérations (lire un élément, stocker un élément, copier un ensemble d'éléments dans un tableau ou copier une série d'éléments d'un tableau vers un autre), la complexité d'avoir plus Les types de tableaux ne sont pas aussi sévères que la complexité d'avoir plus de types de valeurs numériques discrètes directement utilisables.




Related

java optimization types java-api