首页 > 解决方案 > 对于高索引值,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

标签: pythonnumpynumba

解决方案


推荐阅读