python - 为什么 scipy.distance.cdist 在使用 float32(较慢)和 float64(较快)之间有很大的性能差异?
问题描述
为什么 scipy.distance.cdist 在使用 float32 和 float64 之间有很大的性能差异?
from scipy.spatial import distance
import numpy as np
import time
a_float32 = np.empty((1000000, 512), dtype=np.float32)
b_float32 = np.empty((1, 512), dtype=np.float32)
a_float64 = np.empty((1000000, 512), dtype=np.float64)
b_float64 = np.empty((1, 512), dtype=np.float64)
t1 = time.time()
for i in range(100):
distance.cdist(a_float32, b_float32, "sqeuclidean")
t2 = time.time()
print(t2-t1)
t1 = time.time()
for i in range(100):
distance.cdist(a_float64, b_float64, 'sqeuclidean')
t2 = time.time()
print(t2-t1)
在我的电脑上,这段代码为 float32 生成 130.6998474597931 的时间,为 float64 生成 22.450339794158936 的时间,相差 6 倍。float64 比 float32 快的差异如此之大的原因是什么?
然而,如果 b 不是 np.empty((1, 512)),b 是 np.empty((k, 512)) 而 k (>1) 变得越来越大,那么差距似乎变得越来越小。例如,当 k=5 时,我得到 float32 的 222.25975680351257 和 float64 (2x) 的 110.36117148399353。为什么当 k 变大时间隙会变小?
解决方案
实际执行计算的底层 C 代码是使用 Cdouble
变量实现的,这些变量是 64 位浮点值。当您传入 的数组时np.float32
,必须复制数据。
对于您问题的第二部分:更大k
意味着更多的工作,因此复制数据的开销只占总时间的一小部分。
推荐阅读
- facebook-graph-api - Facebook API 因奇怪错误而失败:对象故事规范
- json - Ansible 3.6 json 令牌管理
- go - 对于结构(变量更新)
- ios - 有没有办法让 iOS 13 的新 TestFlight Screenshot beta 反馈进入 Slack
- amazon-web-services - 在 Terraform 中为价格配置 AWS 自动扩展组?
- linux - 用于从作者列表中生成 url 列表的 Linux 脚本
- html - 如何将类型移动到向下搜索文本?
- mybatis - 像这样的 json 的 xml 映射是什么?
- javascript - JavaScript 计算问题
- php - 当我使用变量而不是硬编码数组时,为什么这个 laravel 测试数据库插入不起作用?