For循环与Numpy向量化的计算时间

时间:2018-07-27 00:58:13

标签: python numpy for-loop vectorization

我随机比较了显式for循环和numpy中矢量化实现的计算时间。我进行了100万次迭代,发现了一些惊人的差异。 For循环大约花费 646ms ,而np.exp()函数在不到20ms的时间内计算出相同的结果。

import time
import math
import numpy as np

iter = 1000000

x = np.zeros((iter,1))
v = np.random.randn(iter,1)

before = time.time()

for i in range(iter):
    x[i] = math.exp(v[i])
after = time.time()
print(x)
print("Non vectorized= " + str((after-before)*1000) + "ms")

before = time.time()
x = np.exp(v)
after = time.time()
print(x)
print("Vectorized= " + str((after-before)*1000) + "ms")

我得到的结果:

 [[0.9256753 ]
 [1.2529006 ]
 [3.47384978]
 ...
 [1.14945181]
 [0.80263805]
 [1.1938528 ]]
Non vectorized= 646.1577415466309ms
[[0.9256753 ]
 [1.2529006 ]
 [3.47384978]
 ...
 [1.14945181]
 [0.80263805]
 [1.1938528 ]]
Vectorized= 19.547224044799805ms

我的问题是:

  1. 第二种情况到底发生了什么?第一个正在使用 一个明确的for循环,因此计算时间合理。 第二种情况是“幕后”发生了什么?
  2. 在不使用numpy的情况下(在普通Python中)如何实现这种计算(第二种情况)?

3 个答案:

答案 0 :(得分:2)

正在发生的事情是NumPy正在调用非常擅长矢量算法的高质量数值库(例如BLAS)。

我想您可以确切地调用NumPy使用的确切库,但是,NumPy可能最了解使用哪个库。

答案 1 :(得分:1)

NumPy是Python封装的库和用C语言编写的代码。这是NumPy效率的很大一部分。 C代码直接编译为处理器或GPU执行的指令。另一方面,Python代码必须在执行时进行解释。尽管速度不断提高,但我们可以从诸如Just In Time Compilers之类的先进语言中获得解释性语言,但对于某些任务,它们将永远无法达到编译语言的速度。

答案 2 :(得分:1)

可以归结为Python无法直接访问硬件级别。

Python无法使用大多数现代CPU和GPU拥有的SIMD (Single instruction, multiple data)汇编指令。这些SIMD指令允许在硬件级别一次(在一个时钟周期内)一次对数据向量执行一次操作。

另一方面,NumPy具有用C内置的功能,C是一种能够运行SIMD指令的语言。因此,NumPy可以利用处理器中的矢量化硬件。