2017-02-14 62 views
1

这里的时候发现的点积如此之快:为什么是它np.dot比使用使用np.dot for循环

import numpy as np 
import timeit 

x = np.random.random(size=10**7) 
a = np.ones(x.size) 

%time np.dot(x, a) 

墙时间:11毫秒

5001679.267011214

这里是时间使用for循环:

import numpy as np 
import timeit 

x = np.random.random(size=10**7) 
a = np.ones(x.size) 

def innfeldi(vigur1, vigur2): 
    return sum([vigu1[i]*vigur2[i] for i in range(len(vigur1))]) 

%timeit innfeldi(x, a) 

墙时间:4.78小号

4998161.0032265792

+1

,请复制粘贴文本,而不是截图 – Eric

+1

'for'循环是Python代码,'np.dot'是c代码。 –

+0

'''np.dot()'''使用[BLAS](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms)(如果可用),它对SIMD指令和高速缓存进行了大量优化。它实际上是更多的Fortran代码,而不是这里提到的C。 – sascha

回答

2

因为np.dot执行实际的算术运算和编译代码的封闭循环,这是比Python解释器快得多。

这一原则,分组重复的事情一起,尽可能地切割出解释就是为什么我们可以写在高级语言如Python或MATLAB运行在可接受的速度数字代码。

0

numpy中的很多函数都是用优化的C代码编写的。然而,你正在测试的不是一个公平的比较。

通过在numpy数组上进行迭代,您可以要求python从底层C数组中访问单个元素,将其从C中提取出来并导入到python中,从而创建一个python对象进行操作。这样做有很多开销。

Python将永远不会像快C,但一个更公平的比较是使用numpy的的内置阵列模块,再加上优化的功能

import numpy as np 
import array 
import random 
from operator import mul 

x = np.random.random(size=10**7) 
y = array.array('f', (random.random() for x in range(10**7))) 

a = np.ones(x.shape) 
b = array.array('d', [1]*10**7) 

%%timeit -n3 -r1 
np.dot(x,a) 
# 3 loops, best of 1: 17.1 ms per loop 

%%timeit -n3 -r1 
sum(map(mul, y,b)) 
# 3 loops, best of 1: 777 ms per loop