Я сравниваю производительность numpy vs matlab, в нескольких случаях я заметил, что numpy значительно медленнее (индексирование, простые операции над массивами, такие как абсолютное значение, умножение, сумма и т.д.). Давайте рассмотрим следующий пример, который как-то поражает, включая функцию оцифровать (которую я планирую использовать для синхронизации временных меток):
import numpy as np
import time
scale=np.arange(1,1e+6+1)
y=np.arange(1,1e+6+1,10)
t1=time.time()
ind=np.digitize(scale,y)
t2=time.time()
print 'Time passed is %2.2f seconds' %(t2-t1)
Результат:
Прошло время 55.91 секунд
Теперь попробуйте тот же пример Matlab, используя эквивалентную функцию histc
scale=[1:1e+6];
y=[1:10:1e+6];
tic
[N,bin]=histc(scale,y);
t=toc;
display(['Time passed is ',num2str(t), ' seconds'])
Результат:
Прошло время 0.10237 секунд
Это 560 раз быстрее!
Поскольку я изучаю расширение Python с помощью С++, я внедрил свою собственную версию оцифровки (используя библиотеки boost для расширения):
import analysis # my C++ module implementing digitize
t1=time.time()
ind2=analysis.digitize(scale,y)
t2=time.time()
print 'Time passed is %2.2f seconds' %(t2-t1)
np.all(ind==ind2) #ok
Результат:
Прошло время 0,02 секунды
Есть немного мошенничества, так как моя версия оцифровки предполагает, что входные данные являются монотонными, это может объяснить, почему это даже быстрее, чем Matlab. Однако сортировка массива размером 1e + 6 занимает 0.16 секунд (с numpy.sort), что делает работу моей функции хуже (в 1,6 раза) по сравнению с функцией Matlab histc.
Итак, вопросы:
- Почему numpy.digitize так медленно? Не предполагается ли эта функция записываться в скомпилированный и оптимизированный код?
- Почему моя собственная версия оцифровки намного быстрее, чем numpy.digitize, но все же медленнее, чем Matlab (я вполне уверен, что я использую самый быстрый алгоритм, учитывая, что я предполагаю, что входы уже отсортированы)?
Я использую Fedora 16, и недавно я установил библиотеки ATLAS и LAPACK (но это было так сильно изменилось). Должен ли я, возможно, восстановить numpy? Я не уверен, что если моя установка numpy использует соответствующие библиотеки для достижения максимальной скорости, возможно, Matlab использует лучшие библиотеки.
Обновление
На основании ответов до сих пор я хотел бы подчеркнуть, что функция matlab histc не эквивалентна для numpy.histogram, если кто-то (как и я в этом случае) не заботится о гистограмме. Мне нужен второй вывод hisc, который представляет собой отображение из входных значений в индекс предоставленных входных бинов. Такой вывод обеспечивается с помощью функции numpy оцифровки и поиска. Как говорится в одном из ответов, поиск сортируется намного быстрее, чем оцифровка. Однако поиск в сортировке по-прежнему медленнее, чем Matlab, в два раза:
t1=time.time()
ind3=np.searchsorted(y,scale,"right")
t2=time.time()
print 'Time passed is %2.2f seconds' %(t2-t1)
np.all(ind==ind3) #ok
Результат
Прошло время 0,21 секунды
Итак, теперь вопросы:
-
В чем смысл numpy.digitize, если есть эквивалентная функция numpy.searchsorted, которая 280 раз быстрее?
-
Почему функция Matlab histc (которая также предоставляет вывод numpy.searchsorted) в 2 раза быстрее, чем numpy.searchsorted?