Quel est le coût de la fonction len()
pour les objets intégrés Python? (liste/tuple/chaîne de caractères/dictionnaire)
Merci pour la réponse utile! Y a-t-il des types natifs pour lesquels ce n'est pas le cas?
Quel est le coût de la fonction len()
pour les objets intégrés Python? (liste/tuple/chaîne de caractères/dictionnaire)
Intéressant que la durée d'exécution de la longueur obtenue soit seulement mentionnée pour la liste ici - wiki.python.org/moin/TimeComplexity [non mentionné pour les autres types]
Appeler len()
sur ces types de données est O(1) dans CPython, l'implémentation officielle et la plus courante du langage Python. Voici un lien vers un tableau qui fournit la complexité algorithmique de nombreuses fonctions différentes dans CPython :
Tous ces objets gardent une trace de leur propre longueur. Le temps pour extraire la longueur est court (O(1) en notation big-O) et consiste principalement en [description approximative, écrite en termes de Python, pas en termes de C]: recherchez "len" dans un dictionnaire et envoyez-le à la fonction len intégrée qui recherchera la méthode __len__
de l'objet et l'appellera ... tout ce qu'il a à faire est return self.length
Je pense que c'est la réponse la plus appropriée car cela donne un aperçu des détails de mise en œuvre.
Les mesures ci-dessous fournissent des preuves que len()
est O(1) pour les structures de données souvent utilisées.
Une note concernant timeit
: lorsque le drapeau -s
est utilisé et que deux chaînes sont passées à timeit
, la première chaîne est exécutée une seule fois et n'est pas chronométrée.
$ python -m timeit -s "l = range(10);" "len(l)"
10000000 boucles, meilleure de 3: 0,0677 usec par boucle
$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 boucles, meilleure de 3: 0,0688 usec par boucle
$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 boucles, meilleure de 3: 0,0712 usec par boucle
$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 boucles, meilleure de 3: 0,0699 usec par boucle
$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 boucles, meilleure de 3: 0,0713 usec par boucle
$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 boucles, meilleure de 3: 0,0686 usec par boucle
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 boucles, meilleure de 3: 0,0711 usec par boucle
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 boucles, meilleure de 3: 0,0727 usec par boucle
$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 boucles, meilleure de 3: 0,0682 usec par boucle
$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 boucles, meilleure de 3: 0,0753 usec par boucle
$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 boucles, meilleure de 3: 0,0754 usec par boucle
$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 boucles, meilleure de 3: 0,0713 usec par boucle
$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 boucles, meilleure de 3: 0,0163 usec par boucle
$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 boucles, meilleure de 3: 0,0163 usec par boucle
Ceci n'est pas un si bon benchmark même s'il montre ce que nous savons déjà. Cela est dû au fait que range(10) et range(1000000) ne sont pas censés être en O(1).
Cela est de loin la meilleure réponse. Vous devriez simplement ajouter une conclusion au cas où quelqu'un ne réaliserait pas le temps constant.
Merci pour le commentaire. J'ai ajouté une note sur la complexité O(1) de len()
, et j'ai également corrigé les mesures pour utiliser correctement le drapeau -s
.
len est un O(1) car dans votre RAM, les listes sont stockées sous forme de tables (séries d'adresses contiguës). Pour savoir quand la table s'arrête, l'ordinateur a besoin de deux choses : la longueur et le point de départ. C'est pourquoi len() est un O(1), l'ordinateur stocke la valeur, il lui suffit donc de la rechercher.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.