2016-08-22 3 views
2

Я умножая две большие матрицы, и оказывается, операция выполняется быстрее, когда я первый выполнить возведение в степень на первый вход:Numpy: Отрицательная Время выполнения для операции возведения в степень

import time 
import numpy as np 

a = np.asarray(np.random.uniform(-1,1, (100,40000)), dtype=np.float32) 
b = np.asarray(np.random.uniform(-1,1, (40000,20000)), dtype=np.float32) 

start = time.time() 
d0 = np.dot(a,b) 
print "\nA.B   - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d1 = np.dot(np.exp(a), b) 
print "exp(A).B  - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d2 = np.dot(a, np.exp(b)) 
print "A.exp(B)  - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d3 = np.dot(np.exp(a), np.exp(b)) 
print "exp(A).exp(B) - {:.2f} seconds".format((time.time()-start)) 

Вот результаты:

A.B   1.27 seconds 
exp(A).B  1.15 seconds 
A.exp(B)  7.31 seconds 
exp(A).exp(B) 7.38 seconds 

Может ли кто-нибудь объяснить, что я делаю неправильно, или как это возможно?

ответ

2

То, что вы видите, это причина, почему вы никогда не будете запускать операцию только один раз, когда вы бенчмаркинг, которые это то, что вы пытаетесь здесь сделать. Многие вещи повлияют на результат, который вы видите, когда делаете это только один раз. В этом случае, вероятно, некоторый эффект кеширования. Кроме того, массив b намного больше, чем массив, который нельзя сделать с a против np.exp(a) при выполнении np.exp(b), если вы не работаете в очень контролируемой среде.

Чтобы более точно измерить это, мы можем сократить два последних теста и сфокусироваться на a против exp(a). Кроме того, мы повторяем эту операцию в 10000 раз и уменьшить размер массивов, чтобы избежать необходимости ждать в течение нескольких минут:

import time 
import numpy as np 

a = np.asarray(np.random.uniform(-1,1, (100,400)), dtype=np.float32) 
b = np.asarray(np.random.uniform(-1,1, (400,2000)), dtype=np.float32) 

start = time.time() 
for i in xrange(10000): 
    d0 = np.dot(a,b) 
print "\nA.B   - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
for i in xrange(10000): 
    d0 = np.dot(np.exp(a), b) 
print "exp(A).B  - {:.2f} seconds".format((time.time()-start)) 

Это дает следующий результат на моем компьютере:

A.B   - 7.87 seconds 
exp(A).B  - 13.24 seconds 

Как вы видите , сейчас np.exp(a) занимает больше времени, чем просто доступ к a, как и ожидалось.

1

Я подозреваю, что это вопрос памяти-кэширования, так как инвертирование порядок расстрелах

import time 
import numpy as np 

a = np.asarray(np.random.uniform(-1,1, (100,4000)), dtype=np.float32) 
b = np.asarray(np.random.uniform(-1,1, (4000,20000)), dtype=np.float32) 

start = time.time() 
d1 = np.dot(np.exp(a), b) 
print "exp(A).B  - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d0 = np.dot(a,b) 
print "A.B   - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d1 = np.dot(np.exp(a), b) 
print "exp(A).B  - {:.2f} seconds".format((time.time()-start)) 

start = time.time() 
d0 = np.dot(a,b) 
print "A.B   - {:.2f} seconds".format((time.time()-start)) 

будет по-прежнему вызывает второе заявление, чтобы быть быстрее, чем первый, но второй казни одних и тех же утверждений бегите также быстрее во второй раз.

exp(A).B  - 0.72 seconds 
A.B   - 0.70 seconds 
exp(A).B  - 0.70 seconds 
A.B   - 0.69 seconds 

(я должен был уменьшить размер массивов, чтобы избежать памятей-проблемы.)

Смежные вопросы