Ist es schneller, eine kleine Liste innerhalb einer any () -Anweisung zu durchlaufen?

Betrachten Sie die folgende Operation im Rahmen von Iterables mit geringer Länge:

d = (3, slice(None, None, None), slice(None, None, None))

In [215]: %timeit any([type(i) == slice for i in d])
1000000 loops, best of 3: 695 ns per loop

In [214]: %timeit any(type(i) == slice for i in d)
1000000 loops, best of 3: 929 ns per loop

Einstellung alslist ist 25% schneller als die Verwendung eines Generatorausdrucks?

Warum ist dies der Fall als Einstellung alslist ist eine zusätzliche Operation.

Hinweis: In beiden Läufen erhielt ich die Warnung:The slowest run took 6.42 times longer than the fastest. This could mean that an intermediate result is being cached I

Analys

In diesem speziellen Test,list() Strukturen sind schneller bis zu einer Länge von4 von dem der Generator die Leistung erhöht hat.

Die rote Linie zeigt an, wo dieses Ereignis auftritt, und die schwarze Linie zeigt an, wo beide hinsichtlich der Leistung gleich sind.

Der Code benötigt ca. 1 Minute, um auf meinem MacBook Pro mit allen Kernen ausgeführt zu werden:

import timeit, pylab, multiprocessing
import numpy as np

manager = multiprocessing.Manager()
g = manager.list([])
l = manager.list([])

rng = range(1,16) # list lengths
max_series = [3,slice(None, None, None)]*rng[-1] # alternate array types
series = [max_series[:n] for n in rng]

number, reps = 1000000, 5
def func_l(d):
    l.append(timeit.repeat("any([type(i) == slice for i in {}])".format(d),repeat=reps, number=number))
    print "done List, len:{}".format(len(d))
def func_g(d):
    g.append(timeit.repeat("any(type(i) == slice for i in {})".format(d), repeat=reps, number=number))
    print "done Generator, len:{}".format(len(d))

p = multiprocessing.Pool(processes=min(16,rng[-1])) # optimize for 16 processors
p.map(func_l, series) # pool list
p.map(func_g, series) # pool gens

ratio = np.asarray(g).mean(axis=1) / np.asarray(l).mean(axis=1)
pylab.plot(rng, ratio, label='av. generator time / av. list time')
pylab.title("{} iterations, averaged over {} runs".format(number,reps))
pylab.xlabel("length of iterable")
pylab.ylabel("Time Ratio (Higher is worse)")
pylab.legend()
lt_zero = np.argmax(ratio<1.)
pylab.axhline(y=1, color='k')
pylab.axvline(x=lt_zero+1, color='r')
pylab.ion() ; pylab.show()

Antworten auf die Frage(2)

Ihre Antwort auf die Frage