【发布时间】:2011-08-22 20:13:21
【问题描述】:
以下代码的时间非常奇怪:
import numpy as np
s = 0
for i in range(10000000):
s += np.float64(1) # replace with np.float32 and built-in float
- 内置浮点:4.9 秒
- float64:10.5 秒
- float32:45.0 秒
为什么float64 比float 慢两倍?为什么float32 比 float64 慢 5 倍?
有什么办法可以避免使用np.float64 的惩罚,并让numpy 函数返回内置float 而不是float64?
我发现使用numpy.float64 比Python 的float 慢得多,而numpy.float32 甚至更慢(即使我在32 位机器上)。
numpy.float32 在我的 32 位机器上。因此,每次使用numpy.random.uniform等各种numpy函数时,我都会将结果转换为float32(以便以32位精度执行进一步的操作)。
有没有办法在程序或命令行中的某处设置单个变量,并使所有 numpy 函数返回 float32 而不是 float64?
编辑#1:
numpy.float64 在算术计算中比 float 慢 10 倍。太糟糕了,即使在计算之前转换为浮点数并返回,程序运行速度也快了 3 倍。为什么?有什么办法可以解决吗?
我想强调,我的时间安排不是由于以下任何原因:
- 函数调用
- numpy 与 python float 的转换
- 对象的创建
我更新了我的代码,以更清楚地说明问题所在。使用新代码,我似乎看到使用 numpy 数据类型会带来十倍的性能损失:
from datetime import datetime
import numpy as np
START_TIME = datetime.now()
# one of the following lines is uncommented before execution
#s = np.float64(1)
#s = np.float32(1)
#s = 1.0
for i in range(10000000):
s = (s + 8) * s % 2399232
print(s)
print('Runtime:', datetime.now() - START_TIME)
时间是:
- float64: 34.56s
- float32: 35.11s
- 浮动:3.53s
为了它,我也试过了:
从日期时间导入日期时间 将 numpy 导入为 np
START_TIME = datetime.now()
s = np.float64(1)
for i in range(10000000):
s = float(s)
s = (s + 8) * s % 2399232
s = np.float64(s)
print(s)
print('Runtime:', datetime.now() - START_TIME)
执行时间为13.28 s;实际上,将float64 转换为float 并返回比按原样使用要快3 倍。尽管如此,转换还是要付出代价,因此总体而言,与纯 python float 相比,它的速度要慢 3 倍以上。
我的机器是:
- 英特尔酷睿 2 双核 T9300 (2.5GHz)
- WinXP Professional(32 位)
- ActiveState Python 3.1.3.5
- Numpy 1.5.1
编辑 #2:
感谢您的回答,他们帮助我了解如何处理这个问题。
但我仍然想知道为什么下面的代码在float64 下运行速度比float 慢10 倍的确切原因(也许基于源代码)。
编辑#3:
我在 Windows 7 x64 (Intel Core i7 930 @ 3.8GHz) 下重新运行代码。
同样,代码是:
from datetime import datetime
import numpy as np
START_TIME = datetime.now()
# one of the following lines is uncommented before execution
#s = np.float64(1)
#s = np.float32(1)
#s = 1.0
for i in range(10000000):
s = (s + 8) * s % 2399232
print(s)
print('Runtime:', datetime.now() - START_TIME)
时间是:
- float64:16.1s
- float32:16.1s
- 浮动:3.2s
现在np 的两个浮点数(64 或 32)都比内置的 float 慢 5 倍。尽管如此,还是有很大的不同。我想弄清楚它是从哪里来的。
编辑结束
【问题讨论】:
-
什么版本的 Python?什么版本的numpy?如果是 Python 2.x,请使用 xrange 而不是 range(range 将构建一个巨大的列表)。 float(1) 不是许多人期望经常使用的操作; float(i) 可能更现实一点。为什么要使用 32 位精度?
-
Numpy 说它的浮点数默认为 64 位,这可以解释为什么 32 位浮点数较慢(它必须更改它们)。我不知道为什么指定
float64会使其速度变慢。请注意,AFAIK,您的架构不会影响浮点数据:32 位或 64 位架构仅与内存地址相关。 -
试试
s=10000000.,应该会更快。更严重的是:您正在分析函数调用速度,而 Numpy 在可以矢量化操作时表现出色。import语句是否也在使用内置float的版本中? -
Core 2 Duos 不是 64 位机器吗? ark.intel.com/Product.aspx?id=33917
-
您可以使用
python -mtimeit -s "import numpy; s = numpy.float(1)" "(s + 8) * s % 2399232"来计时。将numpy.float替换为numpy.float32(1)、numpy.float64(1)或1.0以获得其他变体。
标签: python performance numpy floating-point