Великолепный разрыв в производительности между len(arr) и arr.shape[0]

Я нашел это len(arr) почти в два раза быстрее, чем arr.shape[0] и мне интересно, почему.

Я использую Python 3.5.2, Numpy 1.14.2, IPython 6.3.1

Код ниже демонстрирует это:

arr = np.random.randint(1, 11, size=(3, 4, 5))

%timeit len(arr)
# 62.6 ns ± 0.239 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit arr.shape[0]
# 102 ns ± 0.163 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Я также сделал еще несколько тестов для сравнения:

class Foo():
    def __init__(self):
        self.shape = (3, 4, 5)        

foo = Foo()

%timeit arr.shape
# 75.6 ns ± 0.107 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit foo.shape
# 61.2 ns ± 0.281 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit foo.shape[0]
# 78.6 ns ± 1.03 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Итак, у меня есть два вопроса:

1) Почему len(arr) работает быстрее чем arr.shape[0]? (Я бы подумал len будет медленнее из-за вызова функции)

2) Почему foo.shape[0] работать быстрее чем arr.shape[0]? (Другими словами, какие накладные расходы возникают в этом случае при работе с пустыми массивами?)

1 ответ

Решение

Структура данных массива numpy реализована на C. Размеры массива хранятся в структуре C. Они не хранятся в кортеже Python. Поэтому каждый раз, когда вы читаете shape атрибут, создается новый кортеж Python новых целочисленных объектов Python. Когда вы используете arr.shape[0]Затем этот кортеж индексируется, чтобы вытащить первый элемент, что добавляет немного дополнительной информации. len(arr) нужно только создать целое число Python.

Вы можете легко убедиться, что arr.shape создает новый кортеж каждый раз, когда он читается:

In [126]: arr = np.random.randint(1, 11, size=(3, 4, 5))

In [127]: s1 = arr.shape

In [128]: id(s1)
Out[128]: 4916019848

In [129]: s2 = arr.shape

In [130]: id(s2)
Out[130]: 4909905024

s1 а также s2 есть разные ids; это разные объекты кортежей.

Другие вопросы по тегам