我尝试运行以下代码来找出
float64
中的double
和numpy
之间的区别。结果很有趣,因为与 float64
相乘所花费的时间相比,double 类型花费的时间几乎是两倍。需要一些说明。
import time
import numpy as np
datalen = 100000
times = 10000
a = np.random.rand(datalen)
b = np.random.rand(datalen)
da = np.float64(a)
db = np.float64(a)
dda = np.double(a)
ddb = np.double(b)
tic = time.time()
for k in range(times):
dd = dda * ddb
toc = time.time()
print (toc - tic), 'time taken for double'
tic = time.time()
for k in range(times):
d = da * db
toc = time.time()
print (toc - tic), 'time taken for float64'
我认为你正在比较苹果和橙子。
第一个长凳基本上是
a * b
,但第二个a * a
。
我怀疑后者的缓存未命中要少得多。
import numpy as np
np.double is np.float64 # returns True
理论上两者应该是相同的。
基准差异不是由使用的类型引起的 - 请查看其他答案,因为这是一个错误。
关于类型:根据文档,由所使用的平台实现来决定用于表示
double
的位数:Double-precision floating-point number type, compatible with Python float and C double.
(numpy 文档)。因此,在 x86_64 的情况下,它只是 np.float64
的别名。对于其他一些平台,情况可能并非如此。如果这种选择取决于系统,您将受益于本机性能,但可能会引入错误。
如果您使用修复程序运行基准测试,计算出的时间值应该几乎相同。
许多数组操作通常仅受将数组元素从 RAM 加载到缓存中所需时间的限制。
因此,如果每个值的大小较小,或者您不需要将如此多的元素加载到缓存中,您会期望操作速度更快。
这就是为什么你的时间不同:
np.float64
和np.double
实际上并不复制,所以在第一种情况下数组是相同的,而在第二种情况下则不同:
>>> da is db
True
>>> dda is ddb
False
因此可以优化第一种情况,因为您不需要从两个数组加载值,而只需从一个数组加载值。从而使带宽加倍。
但是还有另一件事需要考虑:
np.float64
和np.double
在大多数机器上应该是相同的,但这并不能保证。 np.float64
是固定大小的浮点值(始终为 64 位),而 np.double
取决于机器和/或编译器。在大多数机器上 double
都是 64bit
但这并不总是有保证!因此,如果您的 double
和 float64
宽度不同,您可能会出现速度差异:
>>> np.double(10).itemsize
8
>>> np.float64(10).itemsize
8
>>> np.float64 is np.double
True