В NumPy большие массивы создаются быстрее?

Это тайник, как подсказывает время?

In [55]: timeit a = zeros((10000, 400))
100 loops, best of 3: 3.11 ms per loop

In [56]: timeit a = zeros((10000, 500))
The slowest run took 13.43 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 3.43 µs per loop

Пытался обмануть это, но это не сработало:

In [58]: timeit a = zeros((10000, 500+random.randint(100)))
The slowest run took 13.31 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 4.35 µs per loop

1 ответ

Решение

Причина не в кешировании, а в том, что numpy просто создает заполнитель вместо полного массива. Это можно легко проверить, отслеживая использование ОЗУ, когда вы делаете что-то вроде этого:

a = np.zeros((20000, 20000), np.float64)

Это не выделяет 20k*20k*8byte ~ 3GB на моем компьютере (но может зависеть от ОС, потому что np.zeros использует функцию C calloc). Но будьте осторожны, потому что большинство операций с этим массивом (например, a += 5) немедленно выделит эту память! Убедитесь, что вы используете соответствующий размер по сравнению с вашей оперативной памятью, чтобы вы могли заметить увеличение объема оперативной памяти без чрезмерного ее использования.

В конце концов, это просто откладывает выделение массива, как только вы оперируете с ним, объединенное время выделения и операции должно быть таким, как ожидалось (линейно с количеством элементов). Кажется, вы используете IPython, так что вы можете использовать block-timeit %%timeit:

%%timeit
a = np.zeros((10000, 400))
a += 10
# => 10 loops, best of 3: 30.3 ms per loop

%%timeit
a = np.zeros((10000, 800))
a += 10
# => 10 loops, best of 3: 60.2 ms per loop
Другие вопросы по тегам