Я провел несколько экспериментов и обнаружил несколько случаев, когда стандартные библиотеки Python random
и math
работают быстрее, чем аналог numpy
.
Я думаю, что есть тенденция к тому, что стандартная библиотека Python примерно в 10 раз быстрее для мелкомасштабных операций, тогда как numpy
намного быстрее для крупномасштабных (векторных) операций.Я предполагаю, что numpy
имеет некоторые накладные расходы, которые становятся доминирующими для небольших дел.
Мой вопрос: верна ли моя интуиция?И будет ли вообще целесообразно использовать стандартную библиотеку вместо numpy
для небольших (обычно скалярных) операций?
Примеры приведены ниже.
import math
import random
import numpy as np
Журнал и экспоненциальный
%timeit math.log(10)
# 158 ns ± 6.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit np.log(10)
# 1.64 µs ± 93.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit math.exp(3)
# 146 ns ± 8.57 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit np.exp(3)
# 1.72 µs ± 78.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Генерация нормального распределения
%timeit random.gauss(0, 1)
# 809 ns ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.random.normal()
# 2.57 µs ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Выбор случайного элемента
%timeit random.choices([1,2,3], k=1)
# 1.56 µs ± 55.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.random.choice([1,2,3], size=1)
# 23.1 µs ± 1.04 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
То же самое с массивом NumPy
arr = np.array([1,2,3])
%timeit random.choices(arr, k=1)
# 1.72 µs ± 33.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.random.choice(arr, size=1)
# 18.4 µs ± 502 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
С большим массивом
arr = np.arange(10000)
%timeit random.choices(arr, k=1000)
# 401 µs ± 6.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit np.random.choice(arr, size=1000)
# 41.7 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)