Al perfilar la aplicación de mi Python, descubrí que len()
parece ser muy costoso cuando se utilizan conjuntos. Ver el código de abajo:Rendimiento perfilado de len (conjunto) frente a conjunto .__ len __() en Python 3
import cProfile
def lenA(s):
for i in range(1000000):
len(s);
def lenB(s):
for i in range(1000000):
s.__len__();
def main():
s = set();
lenA(s);
lenB(s);
if __name__ == "__main__":
cProfile.run("main()","stats");
De acuerdo con las estadísticas del perfil del abajo, lenA()
parece ser 14 veces más lento que lenB()
:
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.986 1.986 3.830 3.830 .../lentest.py:5(lenA)
1000000 1.845 0.000 1.845 0.000 {built-in method len}
1 0.273 0.273 0.273 0.273 .../lentest.py:9(lenB)
Me estoy perdiendo algo? Actualmente uso __len__()
en lugar de len()
, pero el código se ve sucio :(
¿Por qué está usando 'cProfile' en lugar de' timeit'? El primero es para encontrar cuellos de botella en programas grandes, y sacrifica cierta precisión a pequeña escala por ello. El último es para medir el rendimiento general de pequeños fragmentos con relativa precisión. 'timeit' debería ser la primera opción para microbenchmarks como este. Y para mí, indica una diferencia menos extrema (0.0879 μs por llamada 'len', 0.158 μs por' .__ len__' call => 'len' siendo 70% más lenta). – delnan
Gracias @delnan, soy bastante nuevo en Python. Usando 'timeit' también obtengo una relación similar. De hecho, mi programa es mucho más grande que el código anterior, pero me sorprendió que la función 'len()' apareciera como uno de los principales cuellos de botella. OK, entonces simplemente ignoraré 'len()' y me concentraré en mis propias funciones, ¿verdad? – Tregoreg