2016-12-13 4 views
2

Est-ce une chose de cache, comme le suggère le temps?En NumPy, les tableaux plus grands sont créés plus rapidement?

In [55]: timeit a = zeros((10000, 400)) 
100 loops, best of 3: 3.11 ms per loop 

In [56]: timeit a = zeros((10000, 500)) 
The slowest run took 13.43 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 3.43 µs per loop 

Essayé de le tromper, mais il ne fonctionne pas:

In [58]: timeit a = zeros((10000, 500+random.randint(100))) 
The slowest run took 13.31 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 4.35 µs per loop 
+0

peut-être je reçois temporelle 100000 boucles, le meilleur de 3: 4,57 ms par boucle 100000 boucles, plus de 3: 4,64 ms par boucle en exécutant votre code, la différence est minime – EdChum

+0

Essayez plutôt 'ones'. Ou ajoutez un 'remplissage '. – hpaulj

+0

Ceci est plutôt cohérent sur ma machine. en utilisant 'ones' est lent (3-4ms) dans les deux tailles. – Bach

Répondre

2

La raison n'est pas mise en cache mais que numpy crée juste un espace réservé à la place du tableau complet. Ceci peut être facilement vérifié en surveillant votre utilisation de la RAM lorsque vous faites quelque chose comme ceci:

a = np.zeros((20000, 20000), np.float64) 

Cela n'alloue pas 20k * 20k * 8byte ~ 3 Go sur mon ordinateur (mais peut-être dépendant de l'OS car np.zeros utilise le Fonction C calloc). Mais soyez prudent car la plupart des opérations sur ce tableau (par exemple a += 5) alloueront immédiatement cette mémoire! Assurez-vous que vous utilisez une taille appropriée par rapport à votre RAM afin que vous remarquiez l'augmentation de RAM sans l'utiliser trop. En fin de compte, cela ne fait que retarder l'allocation de la matrice, dès que vous travaillez avec elle, le timing combiné d'allocation et de fonctionnement devrait être comme prévu (linéaire avec le nombre d'éléments). Il semble que vous utilisez IPython de sorte que vous pouvez utiliser un bloc-timeit %%timeit:

%%timeit 
a = np.zeros((10000, 400)) 
a += 10 
# => 10 loops, best of 3: 30.3 ms per loop 

%%timeit 
a = np.zeros((10000, 800)) 
a += 10 
# => 10 loops, best of 3: 60.2 ms per loop 
+0

Grande explication !! Cela semble être, en effet. – Bach

+0

Notez que cet espace réservé peut être réellement très bon. Si je touche seulement [0,0] après avoir créé un énorme tableau (disons), cela ne coûte pas du tout de temps (et n'alloue pas de mémoire pour le reste du tableau). Je me demande si le seuil de taille est configurable depuis python. – Bach

+0

J'ai essayé de trouver le seuil dans le code source numpy mais je ne l'ai pas trouvé. Notez que cela pourrait même être 'calloc' qui rend cette optimisation. De toute façon, il sera très probablement dans un fichier 'C' donc pas moyen de le changer facilement depuis python. – MSeifert