2010-11-22 3 views
6

J'ai récemment examiné en utilisant list(), dict(), tuple() à la place de [], {}, et (), respectivement lorsque vous avez besoin de créer un vide parmi les trois. Le raisonnement est que cela semblait plus lisible. J'allais demander des opinions sur le style, mais j'ai ensuite décidé de tester la performance. Je l'ai fait:Pourquoi les méthodes list(), dict() et tuple() sont-elles plus lentes que [], {} et()?

>>> from timeit import Timer 
>>> Timer('for x in range(5): y = []').timeit() 
0.59327821802969538 
>>> from timeit import Timer 
>>> Timer('for x in range(5): y = list()').timeit() 
1.2198944904251618 

J'ai essayé dict(), tuple() et list() et la version d'appel de la fonction de chacun était pire incroyablement que la version syntactique ({}[], ()) Donc, j'ai 3 questions:

  1. Pourquoi les appels de fonction sont-ils plus chers?
  2. Pourquoi y a-t-il tellement de différence?
  3. Pourquoi diable faut-il 1,2 secondes pour créer 5 listes vides dans ma minuterie? Je sais que timeit éteint la collecte des ordures, mais cela ne pouvait pas avoir d'effet quand je considérais que je n'utilisais que range(5).
+0

re: opinion de style - J'utilise [] assez fréquemment. Je pense que c'est assez clair. La question de la performance est intéressante cependant. – nmichaels

+0

Il y a beaucoup de choses qui paraissent bizarres à propos de python jusqu'à ce que vous vous y habituiez. Je préférerais toujours '[]' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' que ' acheteur méfiez-vous. – SingleNegationElimination

Répondre

18

L'appel de fonction nécessite une recherche de nom de variable, suivie d'une invocation de fonction. la fonction appelée crée alors une liste et la renvoie. La syntaxe de la liste littérale devient l'interprète de simplement faire une liste:

>>> import dis 
>>> foo = lambda :[] 
>>> bar = lambda :list() 
>>> dis.dis(foo) 
    1   0 BUILD_LIST    0 
       3 RETURN_VALUE   
>>> dis.dis(bar) 
    1   0 LOAD_GLOBAL    0 (list) 
       3 CALL_FUNCTION   0 
       6 RETURN_VALUE   
>>> 
0

Scope sont lookups nécessaires pour trouver dict, tuple et list, et plusieurs champs d'application doivent être recherchées afin de les trouver. Avec le sucre syntaxique, le compilateur peut savoir qu'un objet spécifique doit être créé et peut donc émettre le bytecode approprié pour le faire.

+1

'[]' n'est pas du sucre syntaxique pour quoi que ce soit. C'est une liste littérale. – SingleNegationElimination

+0

@TokenMacGuy: Il s'agit en effet de sucre syntaxique. Les listes peuvent être générées en appelant 'list()', mais le compilateur interprétera les crochets dans le contexte approprié comme créant une liste. –

+2

le compilateur * NE PAS * invoquer 'list()' quand il rencontre '[]'. vois ma réponse. – SingleNegationElimination

2
>>> from dis import dis 

    >>> dis(lambda: list()) 
    1   0 LOAD_GLOBAL    0 (list) 
       3 CALL_FUNCTION   0 
       6 RETURN_VALUE   

    >>> dis(lambda: []) 
    1   0 BUILD_LIST    0 
       3 RETURN_VALUE   
5

Pour répondre # 3. En réalité, le programme répète votre programme 1 000 000 fois par défaut. Donc, en fait, vous créez 5 millions de listes en 1,2 secondes.

+0

merci. Je suppose que la prochaine fois je devrais RTFM :) – orokusaki

Questions connexes