Pourquoi Java a-t-il des primitives pour des nombres de tailles différentes?

20

En Java , il y a des types primitifs pour byte, short, intet longet la même chose pour floatet double. Pourquoi est-il nécessaire qu'une personne définisse le nombre d'octets à utiliser pour une valeur primitive? La taille ne pouvait-elle pas être déterminée de manière dynamique en fonction de la taille du nombre transmis?

Il y a 2 raisons auxquelles je peux penser:

  1. La définition dynamique de la taille des données signifierait qu'elles devraient également pouvoir changer de manière dynamique. Cela pourrait potentiellement causer des problèmes de performances?
  2. Peut-être que le programmeur ne voudrait pas que quelqu'un puisse utiliser un nombre supérieur à une certaine taille et cela lui permet de le limiter.

Je pense toujours qu'il aurait pu y avoir beaucoup à gagner en utilisant simplement un simple intet un floattype, y avait-il une raison spécifique pour laquelle Java a décidé de ne pas suivre cette voie?

yitzih
la source
4
Pour les downvoters, j'ajouterais que cette question est liée à une question à laquelle les chercheurs du compilateur cherchent à répondre .
rwong
Donc, si vous ajoutez à un nombre, vous pensez que le type devrait être changé dynamiquement? Est-ce que je veux même changer le type? Si le nombre est initialisé comme intUnknown alpha = a + b; obtenez-vous que ce serait un peu dur sur le compilateur. Pourquoi est-ce spécifique à Java?
paparazzo
@Paparazzi Il existe des langages de programmation et des environnements d'exécution existants (compilateurs, interprètes, etc.) qui stockeront l'entier de largeur dynamique en fonction de la taille de la valeur réelle (par exemple, le résultat de l'opération d'addition). Les conséquences sont les suivantes: le code à exécuter sur le CPU devient plus compliqué; la taille de cet entier devient dynamique; la lecture d'un entier de largeur dynamique à partir de la mémoire peut nécessiter plus d'un voyage; Les structures (objets) et les tableaux qui contiennent des entiers de largeur dynamique à l'intérieur de leurs champs / éléments peuvent également avoir une taille dynamique.
rwong
1
@tofro je ne comprends pas. Envoyez simplement le nombre dans le format que vous souhaitez: décimal, binaire, etc. La sérialisation est une préoccupation complètement orthogonale.
gardenhead
1
@gardenhead C'est orthogonal, oui, mais ... considérez simplement le cas où vous voulez communiquer entre un serveur écrit en Java et un client écrit en C. Bien sûr, cela peut être résolu avec une infrastructure dédiée. Par exemple, il y a des choses comme developers.google.com/protocol-buffers . Mais c'est un gros marteau pour le petit écrou de transfert d'un nombre entier sur le réseau. (Je sais, ce n'est pas un argument solide ici, mais peut-être un point à considérer - discuter des détails dépasse la portée des commentaires).
Marco13

Réponses:

16

Comme tant d'aspects de la conception des langues, il s'agit d'un compromis entre l'élégance et la performance (sans parler de l'influence historique des langues antérieures).

Alternatives

Il est certainement possible (et assez simple) de créer un langage de programmation qui n'a qu'un seul type de nombres naturels nat. Presque tous les langages de programmation utilisés pour les études universitaires (par exemple PCF, System F) ont ce type de numéro unique, qui est la solution la plus élégante, comme vous l'avez supposé. Mais la conception du langage dans la pratique n'est pas seulement une question d'élégance; nous devons également tenir compte des performances (la mesure dans laquelle les performances sont prises en compte dépend de l'application envisagée du langage). La performance comprend à la fois des contraintes de temps et d'espace.

Contraintes d'espace

Laisser le programmeur choisir le nombre d'octets à l'avance peut économiser de l'espace dans les programmes à mémoire limitée. Si tous vos nombres vont être inférieurs à 256, vous pouvez utiliser 8 fois plus de bytes que longs ou utiliser le stockage enregistré pour des objets plus complexes. Le développeur d'applications Java standard n'a pas à se soucier de ces contraintes, mais elles se présentent.

Efficacité

Même si nous ignorons l'espace, nous sommes toujours contraints par le CPU, qui n'a que des instructions qui fonctionnent sur un nombre fixe d'octets (8 octets sur une architecture 64 bits). Cela signifie que même fournir un seul type de 8 octets longrendrait l'implémentation du langage beaucoup plus simple que d'avoir un type de nombre naturel illimité, en étant capable de mapper les opérations arithmétiques directement sur une seule instruction CPU sous-jacente. Si vous autorisez le programmeur à utiliser des nombres arbitrairement grands, une seule opération arithmétique doit être mappée sur une séquence d'instructions machine complexes, ce qui ralentirait le programme. C'est le point (1) que vous avez évoqué.

Types à virgule flottante

Jusqu'à présent, la discussion n'a porté que sur des entiers. Les types à virgule flottante sont une bête complexe, avec une sémantique et des cas de bord extrêmement subtils. Ainsi, même si nous pourrions remplacer facilement int, long, shortet byteavec un seul nattype, il ne sait pas ce que le type de nombres à virgule flottante même est . Ce ne sont pas de vrais nombres, évidemment, car les vrais nombres ne peuvent pas exister dans un langage de programmation. Ce ne sont pas non plus des nombres tout à fait rationnels (bien qu'il soit simple de créer un type rationnel si vous le souhaitez). Fondamentalement, l'IEEE a décidé d'un moyen d'approcher les nombres réels en quelque sorte, et tous les langages (et programmeurs) y sont restés depuis.

Finalement:

Peut-être que le programmeur ne voudrait pas que quelqu'un puisse utiliser un nombre supérieur à une certaine taille et cela lui permet de le limiter.

Ce n'est pas une raison valable. Premièrement, je ne peux penser à aucune situation dans laquelle les types pourraient naturellement encoder des limites numériques, sans parler des chances astronomiquement faibles que les limites que le programmeur souhaite appliquer correspondraient exactement aux tailles de l'un des types primitifs.

gardenhead
la source
2
la vraie clé du fait que nous avons des flotteurs est que nous avons du matériel dédié pour eux
jk.
l'encodage des limites numériques dans un type se produit absolument dans les langages de type dépendants et, dans une moindre mesure, dans d'autres langages, par exemple comme enums
jk.
3
Les énumérations ne sont pas équivalentes aux entiers. Les énumérations ne sont qu'un mode d'utilisation des types de somme. Le fait que certains langages codent de manière transparente les énumérations sous forme d'entiers est un défaut de langage, pas une fonctionnalité exploitable.
gardenhead
1
Je ne connais pas Ada. Puis-je restreindre les entiers à n'importe quel type, par exemple type my_type = int (7, 2343)?
gardenhead
1
Oui. La syntaxe serait: tapez mon_type est la plage 7..2343
Devsman
9

La raison est très simple: l' efficacité . De multiples façons.

  1. Types de données natifs: plus les types de données d'une langue sont proches des types de données sous-jacents du matériel, plus la langue est considérée comme efficace. (Pas dans le sens où vos programmes seront nécessairement efficaces, mais dans le sens où vous pouvez, si vous savez vraiment ce que vous faites, écrire du code qui fonctionnera aussi efficacement que le matériel peut l'exécuter.) Les types de données proposés par Java correspondent aux octets, mots, mots doubles et quadruples du matériel le plus populaire sur le marché. C'est la façon la plus efficace de procéder.

  2. Surcharge injustifiée sur les systèmes 32 bits: si la décision avait été prise de tout mapper sur une longueur fixe de 64 bits, cela aurait imposé une énorme pénalité aux architectures 32 bits qui nécessitent beaucoup plus de cycles d'horloge pour effectuer un 64- opération de bits qu'une opération de 32 bits.

  3. Perte de mémoire: il y a beaucoup de matériel qui n'est pas trop pointilleux sur l'alignement de la mémoire (les architectures Intel x86 et x64 en sont des exemples), donc un tableau de 100 octets sur ce matériel ne peut occuper que 100 octets de mémoire. Cependant, si vous n'avez plus d'octet et que vous devez utiliser un long à la place, le même tableau occupera un ordre de grandeur de plus de mémoire. Et les tableaux d'octets sont très courants.

  4. Calcul de la taille des nombres: votre idée de déterminer la taille d'un entier de manière dynamique en fonction de la taille du nombre transmis était trop simpliste; il n'y a pas un seul point de «passer» un nombre; le calcul de la taille d'un nombre doit être effectué au moment de l'exécution, à chaque opération pouvant nécessiter un résultat d'une plus grande taille: chaque fois que vous incrémentez un nombre, chaque fois que vous ajoutez deux nombres, chaque fois que vous multipliez deux numéros, etc.

  5. Opérations sur des nombres de tailles différentes: Par la suite, avoir des nombres de tailles potentiellement différentes flottant dans la mémoire compliquerait toutes les opérations: même pour comparer simplement deux nombres, le runtime devrait d'abord vérifier si les deux nombres à comparer sont les mêmes sinon, redimensionnez le plus petit pour qu'il corresponde à la taille du plus grand.

  6. Opérations qui nécessitent des tailles d'opérande spécifiques: Certaines opérations au niveau du bit reposent sur l'entier ayant une taille spécifique. N'ayant pas de taille spécifique prédéterminée, ces opérations devraient être émulées.

  7. Frais généraux du polymorphisme: la modification de la taille d'un nombre au moment de l'exécution signifie essentiellement qu'il doit être polymorphe. Cela signifie à son tour qu'il ne peut pas être une primitive de taille fixe allouée sur la pile, il doit être un objet, alloué sur le tas. C'est terriblement inefficace. (Relisez le numéro 1 ci-dessus.)

Mike Nakis
la source
6

Pour éviter de répéter les points qui ont été discutés dans d'autres réponses, j'essaierai plutôt de décrire plusieurs perspectives.

Du point de vue de la conception de la langue

  • Il est certainement possible de concevoir et de mettre en œuvre un langage de programmation et son environnement d'exécution qui s'adapteront automatiquement aux résultats d'opérations entières qui ne correspondent pas à la largeur de la machine.
  • C'est le choix du concepteur de langage de faire de tels entiers à largeur dynamique le type d'entier par défaut pour ce langage.
  • Cependant, le concepteur de langage doit tenir compte des inconvénients suivants:
    • Le CPU devra exécuter plus de code, ce qui prend plus de temps. Cependant, il est possible d'optimiser pour le cas le plus fréquent dans lequel l'entier s'inscrit dans un seul mot machine. Voir représentation du pointeur balisé .
    • La taille de cet entier devient dynamique.
    • La lecture d'un entier de largeur dynamique à partir de la mémoire peut nécessiter plus d'un voyage.
    • Les structures (objets) et les tableaux qui contiennent des entiers de largeur dynamique à l'intérieur de leurs champs / éléments auront également une taille totale (occupée) qui est dynamique.

Raisons historiques

Ceci est déjà discuté dans l'article Wikipedia sur l'histoire de Java, et est également brièvement discuté dans la réponse de Marco13 .

Je voudrais souligner que:

  • Les concepteurs de langage doivent jongler entre un état d'esprit esthétique et pragmatique. La mentalité esthétique veut concevoir un langage qui n'est pas sujet à des problèmes bien connus, tels que les débordements d'entiers. La mentalité pragmatique rappelle au concepteur que le langage de programmation doit être suffisamment bon pour implémenter des applications logicielles utiles et pour interagir avec d'autres parties logicielles implémentées dans différents langages.
  • Les langages de programmation qui ont l'intention de capturer des parts de marché à partir de langages de programmation plus anciens pourraient être plus enclins à être pragmatiques. Une conséquence possible est qu'ils sont plus disposés à incorporer ou à emprunter des constructions et des styles de programmation existants à partir de ces anciens langages.

Raisons d'efficacité

Quand l'efficacité est-elle importante?

  • Lorsque vous avez l'intention d'annoncer un langage de programmation comme étant apte au développement d'applications à grande échelle.
  • Lorsque vous devez travailler sur des millions et des milliards de petits articles, dans lesquels chaque bit d'efficacité s'additionne.
  • Lorsque vous devez rivaliser avec un autre langage de programmation, votre langage doit fonctionner correctement - il n'a pas besoin d'être le meilleur, mais il aide certainement à rester proche des meilleures performances.

Efficacité du stockage (en mémoire ou sur disque)

  • La mémoire informatique était autrefois une ressource rare. À cette époque, la taille des données d'application pouvant être traitées par un ordinateur était limitée par la quantité de mémoire de l'ordinateur, bien que cela puisse sans doute être résolu en utilisant une programmation intelligente (qui coûterait plus cher à mettre en œuvre).

Efficacité d'exécution (au sein du CPU, ou entre CPU et mémoire)

  • Déjà discuté dans la réponse de gardenhead .
  • Si un programme doit traiter de très grands tableaux de petits nombres stockés consécutivement, l'efficacité de la représentation en mémoire a un effet direct sur ses performances d'exécution, car la grande quantité de données fait que le débit entre le CPU et la mémoire devient un goulot d'étranglement. Dans ce cas, le compactage des données signifie qu'une extraction de ligne de cache unique peut récupérer plus de données.
  • Cependant, ce raisonnement ne s'applique pas si les données ne sont pas stockées ou traitées consécutivement.

La nécessité pour les langages de programmation de fournir une abstraction pour les petits entiers, même s'ils sont limités à des contextes spécifiques

  • Ces besoins surviennent souvent lors du développement de bibliothèques de logiciels, y compris les bibliothèques standard du langage. Voici plusieurs de ces cas.

L'interopérabilité

  • Souvent, les langages de programmation de niveau supérieur doivent interagir avec le système d'exploitation ou des logiciels (bibliothèques) écrits dans d'autres langages de niveau inférieur. Ces langages de niveau inférieur communiquent souvent à l'aide de "structures" , qui est une spécification rigide de la disposition de la mémoire d'un enregistrement composé de champs de différents types.
  • Par exemple, un langage de niveau supérieur peut devoir spécifier qu'une certaine fonction étrangère accepte un chartableau de taille 256. (Exemple.)
  • Certaines abstractions utilisées par les systèmes d'exploitation et les systèmes de fichiers nécessitent l'utilisation de flux d'octets.
  • Certains langages de programmation choisissent de fournir des fonctions utilitaires (par exemple BitConverter) pour aider à compresser et décompresser des entiers étroits en flux binaires et en octets.
  • Dans ces cas, les types entiers plus étroits n'ont pas besoin d'être un type primitif intégré au langage. Au lieu de cela, ils peuvent être fournis en tant que type de bibliothèque.

Gestion des chaînes

  • Il existe des applications dont les principaux objectifs de conception sont de manipuler des chaînes. Ainsi, l'efficacité de la gestion des chaînes est importante pour ces types d'applications.

Gestion du format de fichier

  • De nombreux formats de fichiers ont été conçus avec un état d'esprit de type C. En tant que tel, l'utilisation de champs de faible largeur était répandue.

Souhaitabilité, qualité du logiciel et responsabilité du programmeur

  • Pour de nombreux types d'applications, l'élargissement automatique des nombres entiers n'est en fait pas une fonctionnalité souhaitable. La saturation n'est pas non plus enveloppante (module).
  • De nombreux types d'applications bénéficieront de la spécification explicite du programmeur des plus grandes valeurs autorisées à divers points critiques du logiciel, comme au niveau de l'API.

Considérez le scénario suivant.

  • Une API logicielle accepte une requête JSON. La demande contient un tableau de demandes enfants. La requête JSON entière peut être compressée avec l'algorithme Deflate.
  • Un utilisateur malveillant crée une demande JSON contenant un milliard de demandes enfants. Toutes les demandes d'enfants sont identiques; l'utilisateur malveillant a l'intention que le système brûle certains cycles de processeur en faisant un travail inutile. En raison de la compression, ces requêtes enfants identiques sont compressées à une très petite taille totale.
  • Il est évident qu'une limite prédéfinie sur la taille compressée des données n'est pas suffisante. Au lieu de cela, l'API doit imposer une limite prédéfinie sur le nombre de demandes enfants qui peuvent y être contenues, et / ou une limite prédéfinie sur la taille dégonflée des données.

Souvent, les logiciels qui peuvent évoluer en toute sécurité sur plusieurs ordres de grandeur doivent être conçus à cette fin, avec une complexité croissante. Il ne vient pas automatiquement même si le problème de dépassement d'entier est éliminé. Cela revient à un cercle complet répondant à la perspective de conception de langage: souvent, un logiciel qui refuse d'effectuer un travail lorsqu'un débordement d'entier involontaire se produit (en lançant une erreur ou une exception) est meilleur qu'un logiciel qui se conforme automatiquement à des opérations astronomiquement importantes.

Cela signifie la perspective du PO,

Pourquoi est-il nécessaire qu'une personne définisse le nombre d'octets à utiliser pour une valeur primitive?

n'est pas correcte. Le programmeur doit être autorisé, et parfois obligé, à spécifier la magnitude maximale qu'une valeur entière peut prendre, dans les parties critiques du logiciel. Comme le souligne la réponse de gardenhead , les limites naturelles imposées par les types primitifs ne sont pas utiles à cette fin; le langage doit fournir aux programmeurs des moyens de déclarer des amplitudes et d'appliquer ces limites.

rwong
la source
2

Tout vient du matériel.

Un octet est la plus petite unité de mémoire adressable sur la plupart du matériel.

Chaque type que vous venez de mentionner est construit à partir de plusieurs multiples d'octets.

Un octet fait 8 bits. Avec cela, vous pouvez exprimer 8 booléens mais vous ne pouvez pas rechercher un seul à la fois. Vous vous adressez à 1, vous vous adressez aux 8.

Auparavant, c'était aussi simple que cela, mais nous sommes passés d'un bus 8 bits à un bus 16, 32 et maintenant 64 bits.

Ce qui signifie que même si nous pouvons encore adresser au niveau des octets, nous ne pouvons plus récupérer un seul octet de la mémoire sans obtenir ses octets voisins.

Face à ce matériel, les concepteurs de langage ont choisi de nous permettre de choisir des types qui nous permettaient de choisir des types adaptés au matériel.

Vous pouvez prétendre qu'un tel détail peut et doit être résumé, en particulier dans un langage qui vise à s'exécuter sur n'importe quel matériel. Cela aurait des problèmes de performances cachés, mais vous avez peut-être raison. Cela ne s'est tout simplement pas produit de cette façon.

Java essaie en fait de le faire. Les octets sont automatiquement promus en Ints. Un fait qui vous rendra fou la première fois que vous essayez de faire un travail de changement de bit sérieux.

Alors pourquoi ça n'a pas bien fonctionné?

Le grand argument de vente de Java remonte à l'époque où vous pouviez vous asseoir avec un bon algorithme C connu, le taper en Java, et avec des ajustements mineurs, cela fonctionnerait. Et C est très proche du matériel.

Garder cette taille active et abstraite des types intégraux ne fonctionnait tout simplement pas ensemble.

Alors ils auraient pu. Ils ne l'ont tout simplement pas fait.

Peut-être que le programmeur ne voudrait pas que quelqu'un puisse utiliser un nombre supérieur à une certaine taille et cela lui permet de le limiter.

C'est une pensée valable. Il existe des méthodes pour ce faire. La fonction de serrage pour un. Un langage pourrait aller jusqu'à créer des limites arbitraires dans leurs types. Et lorsque ces limites sont connues au moment de la compilation, cela permettrait d'optimiser la façon dont ces nombres sont stockés.

Java n'est tout simplement pas ce langage.

candied_orange
la source
" Un langage pourrait aller jusqu'à créer des limites arbitraires dans leurs types " Et en effet, Pascal en a une forme avec des types de sous-plages.
Peter Taylor
1

Probablement, une raison importante de la raison pour laquelle ces types existent en Java est simple et malheureusement non technique:

C et C ++ avaient également ces types!

Bien qu'il soit difficile de prouver que c'est la raison, il existe au moins quelques preuves solides: la spécification du langage Oak (version 0.2) contient le passage suivant:

3.1 Types entiers

Les entiers dans le langage Oak sont similaires à ceux en C et C ++, à deux exceptions près: tous les types entiers sont indépendants de la machine, et certaines des définitions traditionnelles ont été modifiées pour refléter les changements dans le monde depuis l'introduction de C. Les quatre types entiers ont des largeurs de 8, 16, 32 et 64 bits et sont signés sauf s'ils sont préfixés par le unsignedmodificateur.

La question pourrait donc se résumer à:

Pourquoi court, int et long ont-ils été inventés en C?

Je ne sais pas si la réponse à la lettre est satisfaisante dans le contexte de la question qui a été posée ici. Mais en combinaison avec les autres réponses ici, il pourrait devenir clair qu'il peut être avantageux d'avoir ces types (indépendamment du fait que leur existence en Java soit seulement un héritage de C / C ++).

Les raisons les plus importantes auxquelles je peux penser sont

  • Un octet est la plus petite unité de mémoire adressable (comme CandiedOrange l'a déjà mentionné). A byteest le bloc élémentaire de construction des données, qui peut être lu à partir d'un fichier ou sur le réseau. Certains de représentation explicite devrait exister (et il existe dans la plupart des langues, même quand il est parfois déguisé).

  • Il est vrai que, dans la pratique, il serait logique de représenter tous les champs et les variables locales à l'aide d'un seul type, et d'appeler ce type int. Il y a une question connexe à ce sujet sur stackoverflow: pourquoi l'API Java utilise-t-elle int au lieu de short ou byte? . Comme je l'ai mentionné dans ma réponse, une justification pour avoir les types plus petits ( byteet short) est que vous pouvez créer des tableaux de ces types: Java a une représentation des tableaux qui est encore plutôt "proche du matériel". Contrairement à d'autres langages (et contrairement aux tableaux d'objets, comme un Integer[n]tableau), un int[n]tableau n'est pas une collection de références où les valeurs sont dispersées dans le tas. Au lieu de cela, il seraen pratique, un bloc d' n*4octets consécutif - un bloc de mémoire de taille et de disposition de données connues. Lorsque vous avez le choix de stocker 1000 octets dans une collection d'objets de valeur entière de taille arbitraire, ou dans un byte[1000](qui prend 1000 octets), ce dernier peut en effet économiser de la mémoire. (Certains autres avantages peuvent être plus subtils et ne deviennent évidents que lors de l'interfaçage de Java avec des bibliothèques natives)


Concernant les points que vous avez spécifiquement interrogés:

La taille ne pouvait-elle pas être déterminée de manière dynamique en fonction de la taille du nombre transmis?

La définition dynamique de la taille des données signifierait qu'elles devraient également pouvoir changer de manière dynamique. Cela pourrait potentiellement causer des problèmes de performances?

Il serait probablement possible de définir dynamiquement la taille des variables, si l'on envisageait de concevoir un tout nouveau langage de programmation à partir de zéro. Je ne suis pas un expert en construction de compilateurs, mais je pense qu'il serait difficile de gérer raisonnablement les collections de types à changement dynamique - en particulier, lorsque vous avez un langage fortement typé. Donc, cela se résumerait probablement à tous les nombres stockés dans un "type de données numériques de précision arbitraire", ce qui aurait certainement des répercussions sur les performances. Bien sûr, il existe des langages de programmation qui sont fortement typés et / ou proposent des types de nombres de taille arbitraire, mais je ne pense pas qu'il existe un véritable langage de programmation à usage général qui soit allé de cette façon.


Notes annexes:

  • Vous vous êtes peut-être posé des questions sur le unsignedmodificateur mentionné dans la spécification Oak. En fait, il contient également une remarque: " unsignedn'est pas encore implémenté; il pourrait ne jamais l'être." . Et ils avaient raison.

  • En plus de vous demander pourquoi C / C ++ avait ces différents types d'entiers, vous vous demandez peut-être pourquoi ils les ont gâchés si horriblement que vous ne savez jamais combien de bits il y inta. Les justifications sont généralement liées à la performance et peuvent être consultées ailleurs.

Marco13
la source
0

Cela montre certainement que vous n'avez pas encore appris les performances et les architectures.

  • Tout d'abord, tous les processeurs ne peuvent pas gérer les gros types, vous devez donc connaître les limites et travailler avec cela.
  • Deuxièmement, des types plus petits signifient plus de performances lors des opérations.
  • De plus, la taille est importante, si vous devez stocker des données dans un fichier ou une base de données, la taille affectera à la fois les performances et la taille finale de toutes les données, par exemple, disons que vous avez une table avec 15 colonnes et que vous vous retrouvez avec plusieurs des millions d'enregistrements. La différence entre choisir une petite taille nécessaire pour chaque colonne ou choisir juste le plus grand type, ce sera une différence de données possibles et de temps dans la performance des opérations.
  • De plus, cela s'applique dans les calculs complexes, où la taille des données en cours de traitement aura un grand impact, comme dans les jeux par exemple.

Ignorer l'importance de la taille des données affecte toujours les performances, vous devez utiliser autant de ressources que nécessaire, mais pas plus, toujours!

C'est la différence entre un programme ou un système qui fait des choses vraiment simples et qui est incroyablement inefficace, qui nécessite beaucoup de ressources et qui rend l'utilisation de ce système très coûteuse; ou un système qui fait beaucoup, mais qui tourne plus vite que les autres et qui est vraiment bon marché.

Nestor Mata Cuthbert
la source
0

Il y a quelques bonnes raisons

(1) alors que le stockage d'un octet variable vers un long est insignifiant, le stockage de millions dans un tableau est très important.

(2) L'arithmétique «native du matériel» basée sur des tailles entières particulières peut être beaucoup plus efficace, et pour certains algorithmes sur certaines plates-formes, cela peut être important.

ddyer
la source