0

Почему statistics.mean() работает так медленно?

18

Я сравнил производительность функции mean из модуля statistics и простого метода sum(l)/len(l), и по какой-то причине функция mean оказывается очень медленной. Я использовал модуль timeit с двумя наборами кода ниже для сравнения, и меня интересует, что может вызывать значительную разницу в скорости выполнения. Я использую Python 3.5.

from timeit import repeat
print(min(repeat('mean(l)',
                 '''from random import randint; from statistics import mean; \
                 l=[randint(0, 10000) for i in range(10000)]''', repeat=20, number=10)))

Код выше выполняется примерно за 0.043 секунды на моем компьютере.

from timeit import repeat
print(min(repeat('sum(l)/len(l)',
                 '''from random import randint; from statistics import mean; \
                 l=[randint(0, 10000) for i in range(10000)]''', repeat=20, number=10)))

Код выше выполняется примерно за 0.000565 секунды на моем компьютере.

Почему наблюдается такая значительная разница в скорости работы этих двух методов?

2 ответ(ов)

0

Если скорость является вашим приоритетом, используйте numpy, scipy или pandas вместо стандартных средств для вычисления усреднения.

Вот пример кода:

from random import randint
from statistics import mean
import numpy as np

# Генерируем список случайных чисел
l = [randint(0, 10000) for i in range(10**6)]

# Вычисляем среднее значение с помощью стандартной библиотеки
mean(l)
# Выдает: 5001.992355

# Замеряем время выполнения
%timeit mean(l)
# Примерный результат: 1 цикл, лучшее из 3: 2.01 с за цикл

# Преобразуем список в массив numpy
a = np.array(l)

# Вычисляем среднее значение с помощью numpy
np.mean(a)
# Выдает: 5001.9923550000003

# Замеряем время выполнения
%timeit np.mean(a)
# Примерный результат: 100 циклов, лучшее из 3: 2.87 мс за цикл

Вывод: Использование numpy делает вычисление в десятки раз быстрее — в моем примере это было примерно 700 раз быстрее, хотя стоит отметить, что numpy не использует алгоритм суммирования Кахана, что может немного повлиять на точность результата.

0

Обе функции len() и sum() являются встроенными функциями Python, написанными на C и, что более важно, оптимизированными для быстрой работы с некоторыми типами объектов, такими как списки.

Вы можете ознакомиться с их реализацией здесь:

https://hg.python.org/sandbox/python2.7/file/tip/Python/bltinmodule.c

Функция statistics.mean() является высокоуровневой функцией, написанной на Python. Посмотрите, как она реализована:

https://hg.python.org/sandbox/python2.7/file/tip/Lib/statistics.py

Вы увидите, что она использует внутреннюю функцию _sum(), которая выполняет несколько дополнительных проверок по сравнению с встроенными функциями.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь