Adloun

Un dictionnaire prend plus de place qu'une liste

Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 5 — Les dictionnaires · Aux frontières du programme

Énoncé

Un dictionnaire prend plus de place qu'une liste. Mesurer avec sys.getsizeof la taille de dictionnaires de , , , et entrées. La croissance est-elle régulière ?

Corrigé


import sys

for n in [0, 5, 10, 100, 1000]:
    print(n, sys.getsizeof({i: i for i in range(n)}))
# 0 64     5 224     10 352     100 4688     1000 36952

La croissance se fait par paliers, pas continûment. La table interne est agrandie d'un coup quand elle se remplit trop, puis ne bouge plus jusqu'au palier suivant : c'est pourquoi et entrées coûtent et octets, sans proportionnalité. Le dictionnaire garde délibérément de la place vide — c'est ce qui limite les collisions, donc ce qui maintient l'accès rapide.

Le prix de la rapidité.


assert sys.getsizeof(list(range(1000))) == 8056
assert sys.getsizeof({i: i for i in range(1000)}) == 36952

Environ quatre fois et demie plus de mémoire pour mille éléments. C'est un arbitrage, comme il y en aura beaucoup en terminale : on paie de la place pour gagner du temps. Sur mille éléments, cela ne se discute pas ; sur cent millions, le choix redevient une vraie question.

Une limite de la mesure. sys.getsizeof ne compte que la structure elle-même, pas les objets qu'elle référence : un dictionnaire de mille longues chaînes annonce la même taille qu'un dictionnaire de mille petits entiers. La mémoire réellement occupée est bien plus grande — ce que l'outil mesure et ce qu'on croit mesurer ne coïncident pas toujours.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.