2010-11-14 38 views
11

en Python, podemos concatenar las listas de dos maneras:¿Es `extender` más rápido que` + = `?

  1. lst.extend (another_lst)
  2. LST + = another_lst

pensé extend sería más rápido que usar +=, porque reutiliza la lista en lugar de crear una nueva usando las otras dos.

Pero cuando lo pruebo con timeit, resulta que += es más rápido,

>>> timeit('l.extend(x)', 'l = range(10); x = range(10)') 
0.16929602623 
>>> timeit('l += x', 'l = range(10); x = range(10)') 
0.15030503273 
>>> timeit('l.extend(x)', 'l = range(500); x = range(100)') 
0.805264949799 
>>> timeit('l += x', 'l = range(500); x = range(100)') 
0.750471830368 

¿Hay algo mal con el código que puse en timeit?

+0

¿Puede mostrarnos los horarios que obtiene? Además, estas operaciones están en su lugar, por lo que no explicaría ninguna diferencia. –

+0

Creo que debería usar listas más grandes, con ese tamaño pequeño, incluso la más mínima actividad de fondo podría arruinar el resultado. – vichle

+0

@ Space_C0wb0y @vischle Obtuve resultados consistentes con lo que informa Satoru incluso con listas de más de 200 elementos. + = es leve, pero consistente, más rápido. Es bastante extraño. –

Respuesta

17

EDITAR: He probado el rendimiento y no puedo replicar las diferencias a ningún nivel significativo.


Aquí está el bytecode - gracias a @John Machin por señalar inconsistencias.

>>> import dis 
>>> l = [1,2,3] 
>>> m = [4,5,6] 
>>> def f1(l, m): 
...  l.extend(m) 
... 
>>> def f2(l,m): 
...  l += m 
... 
>>> dis.dis(f1) 
    2   0 LOAD_FAST    0 (l) 
       3 LOAD_ATTR    0 (extend) 
       6 LOAD_FAST    1 (m) 
       9 CALL_FUNCTION   1 
      12 POP_TOP 
      13 LOAD_CONST    0 (None) 
      16 RETURN_VALUE 
>>> dis.dis(f2) 
    2   0 LOAD_FAST    0 (l) 
       3 LOAD_FAST    1 (m) 
       6 INPLACE_ADD 
       7 STORE_FAST    0 (l) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

en cuenta que extend utiliza un CALL_FUNCTION en lugar de un INPLACE_ADD. Cualquier diferencia de rendimiento trivial probablemente se pueda resumir a esto.

+0

No solo búsqueda de atributos, sino también una llamada a función. – Constantin

+0

@Constantin, principalmente búsqueda de atributos, creo. 'INPLACE_ADD' solo enruta al método' __iadd__' que se haya definido en el objeto. – aaronasterling

+0

@katriealex, @Constantin, @aaronsterling: Sheesh. Es un LOAD_ATTR y un CALL_FUNCTION en comparación con un INPLACE_ADD ** y un STORE_FAST ** –

Cuestiones relacionadas