Мне было любопытно, сколько различий было действительно в использовании np.empty
вместо np.zeros
, а также о разнице в отношении np.ones
.Я запустил этот небольшой скрипт, чтобы сравнить время, необходимое каждому из них для создания большого массива:
import numpy as np
from timeit import timeit
N = 10_000_000
dtypes = [np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64,
np.float16, np.float32, np.float64]
rep= 100
print(f'{"DType":8s} {"Empty":>10s} {"Zeros":>10s} {"Ones":>10s}')
for dtype in dtypes:
name = dtype.__name__
time_empty = timeit(lambda: np.empty(N, dtype=dtype), number=rep) / rep
time_zeros = timeit(lambda: np.zeros(N, dtype=dtype), number=rep) / rep
time_ones = timeit(lambda: np.ones(N, dtype=dtype), number=rep) / rep
print(f'{name:8s} {time_empty:10.2e} {time_zeros:10.2e} {time_ones:10.2e}')
И в результате получил следующую таблицу:
DType Empty Zeros Ones
int8 1.39e-04 1.76e-04 5.27e-03
int16 3.72e-04 3.59e-04 1.09e-02
int32 5.85e-04 5.81e-04 2.16e-02
int64 1.28e-03 1.13e-03 3.98e-02
uint8 1.66e-04 1.62e-04 5.22e-03
uint16 2.79e-04 2.82e-04 9.49e-03
uint32 5.65e-04 5.20e-04 1.99e-02
uint64 1.16e-03 1.24e-03 4.18e-02
float16 3.21e-04 2.95e-04 1.06e-02
float32 6.31e-04 6.06e-04 2.32e-02
float64 1.18e-03 1.16e-03 4.85e-02
Из этогоЯ извлекаю два несколько удивительных вывода:
- Практически нет разницы между показателями
np.empty
и np.zeros
, возможно, за исключением некоторой разницы дляint8
.Я не понимаю, почему это так.Предполагается, что создание пустого массива будет быстрее, и на самом деле я видел сообщения об этом (например, Скорость np.empty против np.zeros ). - Существует большая разница между
np.zeros
и np.ones
.Я подозреваю, что это связано с высокопроизводительными средствами для обнуления памяти, которые не относятся к заполнению области памяти константой, но я действительно не знаю, как или на каком уровне это работает.
Чем объясняются эти результаты?
Я использую NumPy 1.15.4 и Python 3.6 Anaconda в Windows 10 (с MKL), и у меня есть процессор Intel Core i7-7700K.
РЕДАКТИРОВАТЬ: Согласно предложению в комментариях, я попытался выполнить тест, чередуя каждое отдельное испытание и усредняя в конце, но я не мог видеть существенную разницу в результатах.Однако, в связи с этим, я не знаю, есть ли в NumPy какие-либо механизмы для повторного использования памяти только что удаленного массива, что сделало бы меры нереалистичными (хотя времена, похоже, даже увеличиваются с размером типа данных)для пустых массивов).