Почему numpy намного медленнее, чем matlab в примере оцифровки?

Я сравниваю производительность numpy и 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 с помощью C ++, я реализовал свою собственную версию оцифровки (с использованием расширенных библиотек для расширения):

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, но все же медленнее, чем Matlab (я совершенно уверен, что использую максимально быстрый алгоритм, учитывая, что Я предполагаю, что входные данные уже отсортированы)?

Я использую Fedora 16 и недавно установил библиотеки ATLAS и LAPACK (но производительность сильно изменилась). Может, мне пересобрать numpy? Я не уверен, что моя установка numpy использует соответствующие библиотеки для достижения максимальной скорости, возможно, Matlab использует лучшие библиотеки.

Обновление

На основании полученных ответов я хотел бы подчеркнуть, что функция Matlab histc не эквивалентна numpy.histogram , если кого-то (как меня в данном случае) не волнует гистограмма. Мне нужен второй вывод hisc, который представляет собой отображение входных значений в индекс предоставленных входных ящиков. Такой вывод обеспечивают функции numpy , оцифровка и searchsorted . Как говорится в одном из ответов, searchsorted намного быстрее, чем оцифровка . Однако поисковая сортировка все еще медленнее, чем Matlab в 2 раза :

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 секунды

Итак, теперь вопросы:

  1. В чем смысл имеющий numpy.digitize , если есть эквивалентная функция numpy.searchsorted , что в 280 раз быстрее ?

  2. Почему функция Matlab histc (которая также обеспечивает вывод numpy.searchsorted ) В 2 раза быстрее , чем numpy.searchsorted ?

14
задан Saullo G. P. Castro 12 May 2013 в 21:21
поделиться