No sé si los siguientes dos fragmentos tienen el mismo rendimiento.

Código1:

for fid1 in FId1:
    if fid1 in [i['FId'] for i in entity['F']]:
        res.append([intId1,fid1,entity['Id'],intId2])

Código2:

 temp = [i['FId'] for i in entity['F']]
 tempid = entity['Id']
 for fid1 in FId1:
        if fid1 in temp:
            res.append([intId1,fid1,tempid,intId2])

Básicamente, en el bucle no cambio la entidad.

Creo que en Code1, sin optimización, generaría esa lista en cada bucle. Aunque es más legible, ¿sería más lento?

Y, por lo tanto, trato de almacenar la temperatura, para que la lista se genere solo una vez.

El rendimiento es bastante importante para esta tarea ...

-1
Euclid Ye 11 may. 2016 a las 16:11

3 respuestas

La mejor respuesta

Sí, exactamente, el primer código generará la lista temporal para cada iteración. Esto es cierto para CPython (el intérprete nativo de Python). Técnicamente, la optimización que usó en el Código 2 se llama precomputación.

Sin embargo, si usa un optimizador como PyPy, puede ser diferente, ya que puede detectar para esta instancia que su lista nunca cambia y, por lo tanto, almacenarla como una constante.

3
gaborous 11 may. 2016 a las 13:14

Cuando el rendimiento importa, mídelo.

Si no mide el rendimiento, no sabe qué rendimiento está logrando. Y lo que es más importante, no sabrá si ese rendimiento mejora o empeora con futuros cambios.

2
John Zwinck 11 may. 2016 a las 13:13

No solo cree esa lista fuera del bucle, cámbiela para establecerla (o inmovilícela si es constante): experimentará el tiempo de prueba de membresía O(1).

>>> timeit.timeit('123456 in s', setup='s = frozenset(xrange(1000000))', number=1000)
7.14463625257622e-05
>>> timeit.timeit('123456 in l', setup='l = list(xrange(1000000))', number=1000)
2.899147340951913
2
Łukasz Rogalski 11 may. 2016 a las 13:21