为什么 np.dot 比使用 for 循环查找点积要快得多



以下是使用 np.dot 的时间:

import numpy as np
import timeit
x = np.random.random(size=10**7)
a = np.ones(x.size)
%time np.dot(x, a)

挂孔时间:11 ms

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

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

这个原则,将重复的东西组合在一起并尽可能减少解释器,这就是为什么我们可以用高级语言(如 Python 或 matlab(编写以可接受的速度运行的数字代码。

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

最新更新