Так что, немного поиграв, я смог значительно сократить время работы с помощью векторизации NumPy и JIT-компилятора Numba.Возвращаясь к исходному коду:
arr = mp.RawArray(ctypes.c_uint, n*m)
def fun(i):
for j in range(i-1,0,-1):
count = 0
for k in range(0,m):
count += (arr[i*m+k] == arr[j*m+k])
if count/m > 0.7:
return (i,j)
return ()
Мы можем опустить нижнее утверждение return
, а также отказаться от идеи использования count
полностью, оставив нам:
def fun(i):
for j in range(i-1,0,-1):
if sum(arr[i*m+k] == arr[j*m+k] for k in range(m)) > 0.7*m:
return (i,j)
Затем мы изменяем массив arr
на формат NumPy:
np_arr = np.frombuffer(arr,dtype='int32').reshape(m,n)
Здесь важно отметить, что мы не используем массив NumPy в качестве массива общей памяти, чтобы он был написано из нескольких процессов, избегая ловушек.
Наконец, мы применяем декоратор Numba и переписываем функцию sum
в векторной форме, чтобы она работала с новым массивом:
import numba as nb
@nb.njit(fastmath=True,parallel=True)
def fun(i):
for j in range(i-1, 0, -1):
if np.sum(np_arr[i] == np_arr[j]) > 0.7*m:
return (i,j)
Это уменьшило время бега до 7,9 с , что для меня определенно победа.