np.array == num сравнение очень медленное? Можно ли использовать мультипроцессор для его ускорения? - PullRequest
1 голос
/ 04 июня 2019

Является ли == сравнение большого np.array с одним числом очень низким в python?Я использовал line_profiler, чтобы найти узкое место в моем коде.Узкое место - это простое сравнение массива 1d np.ar с постоянным числом.На его долю приходится 80% общего времени выполнения.Я сделал что-то не так, заставляя это быть таким медленным?Есть ли способ ускорить это?

Я пытался использовать многопроцессорность, однако в тестовом коде (фрагмент 2) использование многопроцессорности медленнее, чем последовательный запуск и непосредственное использование map.Кто-нибудь может объяснить это явление?

Любые комментарии или предложения искренне приветствуются.

Фрагмент 1:

Строка # Хиты Время на удар% Содержание строки времени

38 12635 305767927.0 24200.1 80.0 res = map (logicEqual, сборка)

def logicalEqual(x):
         return F[:,-1] == x

assembly = [1,2,3,4,5,7,8,9,...,25]

F - это типизированный int (281900, 6) np.array

Фрагмент 2:

import numpy as np
from multiprocessing import Pool
import time

y=np.random.randint(2, 20, size=10000000)

def logicalEqual(x):
    return y == x

p=Pool()
start = time.time()
res0=p.map(logicalEqual, [1,2,3,4,5,7,8,9,10,11,12,13,14,15])
# p.close()
# p.join()
runtime = time.time()-start
print(f'runtime using multiprocessing.Pool is {runtime}')

res1 = []
start = time.time()
for x in [1,2,3,4,5,7,8,9,10,11,12,13,14,15]:
    res1.append(logicalEqual(x))
runtime = time.time()-start
print(f'sequential runtime is {runtime}')


start = time.time()
res2=list(map(logicalEqual,[1,2,3,4,5,7,8,9,10,11,12,13,14,15]))
runtime = time.time()-start
print(f'runtime is {runtime}')

runtime using multiprocessing.Pool is 0.3612203598022461
sequential runtime is 0.17401981353759766
runtime is  0.19697237014770508

1 Ответ

0 голосов
/ 05 июня 2019

Сравнение массивов быстрое, поскольку оно выполняется в коде C, а не в Python.

x = np.random.rand(1000000)
y = 4.5
test = 0.55
%timeit x == test
386 µs ± 4.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit y == test
33.2 ns ± 0.121 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Таким образом, сравнение одного поплавка Python с другим занимает 33 * 10 ^ -9 с, в то время как сравнение 1E6 числа с плавающей запятой занимает всего 386 мкс / 33 нс ~ = 11700 раз дольше, несмотря на сравнение еще 1000000 значений. То же самое верно для целых (377 мкс против 34 нс). Но, как упоминалось в комментариях Dunes, сравнение большого количества значений занимает много циклов. С этим ничего не поделаешь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...