python - 对于高索引值,numpy 数组中的索引很慢
问题描述
我正在尝试编写一个函数来计算信号的互相关,in_
,结果放在buffer
. 但是,我不明白为什么这个实现:
import numba as nb
import numpy as np
from numba.pycc import CC
cc = CC('test')
@nb.njit
@cc.export('diff', '(f4[:], i8, f4[:], i8)')
def diff(in_, in_i, buffer, half_buffer_size):
end_i = in_i+half_buffer_size
for tau in range(half_buffer_size):
temp = np.float32(0.0)
for i in range(in_i, end_i):
delta = in_[i] - in_[i + tau]
temp += delta*delta
buffer[tau] = temp
花费的时间是这个实现的两倍:
@nb.njit
@cc.export('diff', '(f4[:], i8, f4[:], i8)')
def diff(in_, in_i, buffer, half_buffer_size):
a = in_[in_i:2*half_buffer_size+in_i]
for tau in range(half_buffer_size):
temp = np.float32(0.0)
for i in range(half_buffer_size):
delta = a[i] - a[i + tau]
temp += delta*delta
buffer[tau] = temp
我什至试过这个,但它比上面的两个还要慢:
@nb.njit
@cc.export('diff', '(f4[:], i8, f4[:], i8)')
def diff(in_, in_i, buffer, half_buffer_size):
end_i = in_i+half_buffer_size
i_list = list(range(in_i, end_i))
for tau in range(half_buffer_size):
temp = np.float32(0.0)
for i in i_list:
delta = in_[i] - in_[i + tau]
temp += delta*delta
buffer[tau] = temp
我使用以下代码调用此代码:
@cc.export('test', '(f4[:], f4[:], i8, i8)')
def test(in_, buffer, half_buffer_size, num_of_iterations):
for i in range(num_of_iterations):
diff(in_, i, buffer, half_buffer_size)
in_ = np.zeros(shape=100000, dtype=np.float32)
buffer = np.zeros(shape=300, dtype=np.float32)
test.test(a1, a2, 150, 16000) # simulate one second of input samples
所以我第一次实现的时间为 0.65 秒,第二次为 0.35 秒,第三次为 0.8 秒。为什么第二个实现这么快?这个 diff 函数代表了 YIN 音高跟踪算法的第一步:http: //audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf
解决方案
推荐阅读
- javascript - 使用 JavaScript 在 URL 中添加 GET 参数
- c++ - 将对象插入 std::map 时构造函数中的变量地址
- realm - Realm db 的撤消管理
- .net - 如何为 ARM 平台构建 Tizen C# .NET Wearable TPK 并发布到三星卖家门户?
- javascript - 在 dataLoader amchart v3 中循环
- java - 有没有办法根据给定的字符串设置实例的成员变量?
- firebase - Flutter Cloud Firestore 仅在调试时获取最新数据
- c - 如何订购相互依赖的功能?
- javascript - 将“keydown”事件侦听器添加到文档中,输入字段除外
- javascript - 如何在 expressjs 中调用多个文件 .pug?