Почему Python3.6 показывает лучшие результаты, чем 3.7? - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть следующий код (бесполезно, только для тестирования производительности)

class A:
    def __init__(self, i):
        self.i = i

start = datetime.now()
foo = {}
for i in range(10000000):
    foo[i] = A(i)

print('\nSpent: [ {} ] seconds!'.format((datetime.now()-start).total_seconds()))

Дело в том, что когда я запускаю его с Python3.7, я получаю следующие результаты

Spent: [ 7.644764 ] seconds!

Но когда я запускаю его с Python3.6

Spent: [ 6.521555 ] seconds!

Итак, вопрос в том, могу ли я что-то неправильно понять, или старый Python работает быстрее, и мне следует использовать старый?

UPD: Как указывалось в комментариях, я использовал модуль timeit, здесь результаты

python3.7 -m timeit '"-".join(str(n) for n in range(2000000))'
1 loop, best of 5: 499 msec per loop

python3.6 -m timeit '"-".join(str(n) for n in range(2000000))'
10 loops, best of 3: 405 msec per loop

Результаты с timeit все еще плохи для 3,7, действительно ли они медленнее, чем 3,6?

1 Ответ

0 голосов
/ 27 сентября 2018

Ваш метод синхронизации неверен.Через 6-7 секунд современная ОС не предоставит Python эксклюзивный доступ к процессору, происходят и другие вещи, так как ОС переключается между процессами, очищает дисковые буферы для записываемых файлов, выполняет запланированные сетевые события и т. Д.

Вы также генерируете довольно много объектов, которые все загружаются в память, поэтому Python должен запросить у ОС выделение дополнительных страниц памяти.Это зависит от того, что еще ваш компьютер выполнял в то время, насколько быстро может быть предоставлена ​​эта память.Похоже, что вы запустили Python 3.6 секунды, поэтому вполне может оказаться, что память, освобожденная и перераспределенная для запуска Python 3.7, все еще доступна для запуска 3.6, а недавно освобожденную память намного легче перераспределить для ОС.

Далее, вы использовали довольно неточный таймер настенных часов, чтобы оценить свое выступление.datetime.now() подходит для людей, которые хотят знать текущее время, не подходит для измерения производительности.Для последней задачи в Python доступны более специализированные часы.У самого Python также есть фоновый процесс, называемый сборщик мусора , который также захочет получить некоторое время для выполнения своей работы, влияя на то, как Python выполняет задачи, которые вы ему дали.

Вместо этого вынужно разделить различные проблемы, которые Python должен решить здесь, на отдельные тесты.Запустите эти отдельные тесты в контролируемых условиях, с точными часами и с максимально возможным количеством отвлекающих факторов.Запустите эти тесты много, много раз , а затем выберите либо среднее время (если у вас есть только агрегат), либо лучшее время из множества повторений.

Для этого в Python есть библиотека,называется timeit.Используйте это, чтобы только создавать экземпляры, но не хранить их все в словаре.Как указывалось ранее, распределение памяти зависит от времени ОС, а не от Python.Не забывайте повторять ваши тесты;если -m timeit запускает тест только один раз , вы действительно не можете доверять временным показателям, уменьшите работу, проделанную в тесте.

Далее, если ваша цель - сравнить Python 3,6 с 3,7на общих условиях производительности , а не на конкретном микробенчмарке, тогда вам потребуется широкий спектр тестов.Материал постоянно меняется с 3.x до 3.x + 1 релизов.Не основывайте ничего на одном соединении строк или тесте создания экземпляра.И знайте, что разработчики Python уже сделали всю эту работу.См. https://speed.python.org/ для полного набора тестов и таймингов, которые основная команда использует для мониторинга производительности, или посмотрите PyPerformance suite для другого такого теста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...