Я сделал тест для нескольких методов:
argwhere
nonzero
как в вопросе
.tostring()
как в ответе @Rob Reilink
- цикл питона
- петля Фортрана
Доступны Python и Fortran . Я пропустил бесперспективные, такие как преобразование в список.
Результаты в логарифмическом масштабе. Ось X - это положение стрелки (требуется больше времени, чтобы определить, находится ли она дальше вниз по массиву); Последнее значение - это игла, которой нет в массиве. Ось Y - это время, чтобы найти его.
Массив содержал 1 миллион элементов, и тесты проводились 100 раз. Результаты все еще немного колеблются, но качественная тенденция ясна: Python и f2py выходят из первого элемента, поэтому они масштабируются по-разному. Python становится слишком медленным, если стрелка находится не в первых 1%, тогда как f2py
быстр (но вам нужно его скомпилировать).
Подводя итог, f2py - самое быстрое решение , особенно если игла появляется довольно рано.
Он не встроен, что раздражает, но на самом деле это всего 2 минуты работы. Добавьте this в файл с именем search.f90
:
subroutine find_first(needle, haystack, haystack_length, index)
implicit none
integer, intent(in) :: needle
integer, intent(in) :: haystack_length
integer, intent(in), dimension(haystack_length) :: haystack
!f2py intent(inplace) haystack
integer, intent(out) :: index
integer :: k
index = -1
do k = 1, haystack_length
if (haystack(k)==needle) then
index = k - 1
exit
endif
enddo
end
Если вы ищете что-то отличное от integer
, просто измените тип. Затем скомпилируйте, используя:
f2py -c -m search search.f90
после чего вы можете сделать (из Python):
import search
print(search.find_first.__doc__)
a = search.find_first(your_int_needle, your_int_array)