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