Использование вашей функции и следующего кода для профилирования скорости
import time
shape = (10, 1440)
matrix = np.zeros(shape)
sim_start = 0
sim_end = 1440
searches = generate_searches(1000000, sim_start, sim_end)
def reset():
matrix[:] = 0
def test_matrix_speed():
for i in searches:
search_start = i[0]
search_end = i[1]
availability = search_and_book_availability(matrix, search_start, search_end)
def timeit(func):
# warmup
reset()
func()
reset()
start = time.time()
func()
end = time.time()
return end - start
print(timeit(test_matrix_speed))
Я нахожу порядка 11,5 с для jit
ed версии и 7,5 с без jit
.Я не эксперт по numba, но для этого она оптимизирует числовой код, написанный не векторизованным способом, в частности, с явными циклами for
.В вашем коде их нет, вы используете только векторизованные операции.Поэтому я ожидал, что jit
не превзойдет базовое решение, хотя должен признать, что удивился, увидев его намного хуже.Если вы хотите оптимизировать свое решение, вы можете сократить время выполнения (по крайней мере, на моем ПК) следующим кодом:
def search_and_book_availability_opt(matrix, search_start, search_end):
search_slice = matrix[:, search_start:search_end]
# we don't need to sum in order to check if all elements are 0.
# ndarray.any() can use short-circuiting and is therefore faster.
# Also, we don't need the selected values from np.where, only the
# indexes, so np.nonzero is faster
bookable, = np.nonzero(~search_slice.any(axis=1))
# short circuit
if bookable.size == 0:
return False
# we can perform random choice even if size is 1
id_to_book = np.random.choice(bookable)
matrix[id_to_book, search_start:search_end] = 1
return True
и инициализировать matrix
как np.zeros(shape, dtype=np.bool)
вместопо умолчанию float64
.Я могу получить время выполнения около 3,8 с, улучшение на ~ 50% по сравнению с вашим неопубликованным решением и улучшение на ~ 70% по сравнению с джитированной версией.Надеюсь, это поможет.