According to the answers from this question and also according to numpy, matrix multiplication of 2-D arrays is best done via a @ b
, or numpy.matmul(a,b)
as compared to a.dot(b)
.
If both a and b are 2-D arrays, it is matrix multiplication, but using matmul or a @ b is preferred.
I did the following benchmark and found contrary results.
Questions: Is there an issue with my benchmark? If not, why does Numpy not recommend a.dot(b)
when it is faster than a@b
or numpy.matmul(a,b)
?
Benchmark used python 3.5 numpy 1.15.0.
$ pip3 list | grep numpy
numpy 1.15.0
$ python3 --version
Python 3.5.2
Benchmark code:
import timeit
setup = '''
import numpy as np
a = np.arange(16).reshape(4,4)
b = np.arange(16).reshape(4,4)
'''
test = '''
for i in range(1000):
a @ b
'''
test1 = '''
for i in range(1000):
np.matmul(a,b)
'''
test2 = '''
for i in range(1000):
a.dot(b)
'''
print( timeit.timeit(test, setup, number=100) )
print( timeit.timeit(test1, setup, number=100) )
print( timeit.timeit(test2, setup, number=100) )
Results:
test : 0.11132473500038031
test1 : 0.10812476599676302
test2 : 0.06115105600474635
Add on results:
>>> a = np.arange(16).reshape(4,4)
>>> b = np.arange(16).reshape(4,4)
>>> a@b
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
>>> np.matmul(a,b)
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
>>> a.dot(b)
array([[ 56, 62, 68, 74],
[152, 174, 196, 218],
[248, 286, 324, 362],
[344, 398, 452, 506]])
Because the Numpy array is densely packed in memory due to its homogeneous type, it also frees the memory faster. So overall a task executed in Numpy is around 5 to 100 times faster than the standard python list, which is a significant leap in terms of speed.
Because np. dot executes the actual arithmetic operations and the enclosing loop in compiled code, which is much faster than the Python interpreter.
The matmul() function broadcasts the array like a stack of matrices as elements residing in the last two indexes, respectively. The numpy. dot() function, on the other hand, performs multiplication as the sum of products over the last axis of the first array and the second-to-last of the second.
dot() will multiply every value of the array by the scalar (i.e., scalar multiplication). If both inputs are 1-dimensional arrays, np. dot() will compute the dot product of the inputs. If both inputs are 2-dimensional arrays, then np.
Your premise is incorrect. You should use larger matrices to measure performance to avoid function calls dwarfing insignificant calculations.
Using Python 3.60 / NumPy 1.11.3 you will find, as explained here, that @
calls np.matmul
and both outperform np.dot
.
import numpy as np
n = 500
a = np.arange(n**2).reshape(n, n)
b = np.arange(n**2).reshape(n, n)
%timeit a.dot(b) # 134 ms per loop
%timeit a @ b # 71 ms per loop
%timeit np.matmul(a,b) # 70.6 ms per loop
Also note, as explained in the docs, np.dot
is functionally different to @
/ np.matmul
. In particular, they differ in treatment of matrices with dimensions greater than 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With