Indexing within numpy array slow for high index values

Viewed 122

I'm trying to write a function to compute the cross correlation of a signal, in_, with the result placed in buffer. However, I can't understand why this implementation:

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

takes twice as long as this implementation:

@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

I even tried this but it is even slower than the two above:

@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

I am calling this code using the following:

@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

So I am getting 0.65 seconds for the first implementation, 0.35 for the second and 0.8 for the third. Why is the second implementation so much faster? This diff function represents the first step in the YIN pitch tracking algorithm: http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf

0 Answers
Related