que tienen un simple Sieve of Eratosthanes aplicación de la siguiente manera:Benchmarking en Python: ¿Por qué mi código se ejecuta más lento con la repetición?
# Generate all primes less than k
def sieve(k):
s = [True] * k
s[0] = s[1] = False
for i in range(4, k, 2):
s[i] = False
for i in range(3, int(sqrt(k)) + 2, 2):
if s[i]:
for j in range(i ** 2, k, i * 2):
s[j] = False
return [2] + [ i for i in range(3, k, 2) if s[i] ]
estoy Benchmarking este código al generar repetidamente primos bajo 10M:
st = time()
for x in range(1000):
rt = time()
sieve(10000000)
print "%3d %.2f %.2f" % (x, time() - rt, (time() - st)/(x + 1))
Estoy confundido, como el tiempo que aumenta la ejecución de prueba por marcadamente :
run t avg
0 1.49 1.49
1 1.79 1.66
2 2.23 1.85
3 2.72 2.07
4 2.67 2.20
5 2.87 2.31
6 3.05 2.42
7 3.57 2.56
8 3.38 2.65
9 3.48 2.74
10 3.81 2.84
11 3.75 2.92
12 3.85 2.99
13 4.14 3.07
14 4.02 3.14
15 4.05 3.20
16 4.48 3.28
17 4.41 3.34
18 4.19 3.39
19 4.22 3.43
20 4.65 3.49
Sin embargo, el cambio de cada instancia de range
-xrange
elimina el problema:
run t avg
0 1.26 1.26
1 1.23 1.28
2 1.24 1.27
3 1.25 1.26
4 1.23 1.26
5 1.23 1.25
6 1.25 1.25
7 1.25 1.25
8 1.23 1.25
9 1.25 1.25
10 1.24 1.25
¿Por qué es este el caso? ¿Es realmente todo sobre GC? 3 veces más lento después de 20 carreras parece mucho ...
p.s. ['timeit'] (http://docs.python.org/library/timeit.html) es una forma más sencilla de programar su código. – nneonneo
No solo recolección de basura, asignación de memoria también para hacer todos esos rangos. Usar 'range' cuando no necesitas una lista es un desperdicio. Esta es la razón por la cual el 'range' de Python 3 funciona como' xrange' de Python 2. Entonces, si realmente necesita una lista, escriba 'list (range (n))'. –
¿Es útil ejecutar 'gc.collect' después de cada ejecución? – nneonneo