Я экспериментирую с большими списками, чтобы протестировать кластер RPi. Я создаю список строк символов, хэши которых в конечном итоге буду вычислять для имитации майнинга криптовалюты. Код работает на Raspberry Pi 3B Rev 1.2.
Код для создания списка:
from pympler import asizeof
import itertools
import time
start = time.process_time()
combos = list(itertools.combinations_with_replacement('abcdefghijlkmnopqrstuvwxyz', 6))
stop = time.process_time()
print(len(combos), asizeof.asizeof(combos)/1e6, (stop-start))
Результаты:
andrew@master:~ $ python mem_test_1.py
736281 70.727904 0.68859771
Проблема в том, что фактическое время (по секундомеру) ближе к 45 секундам. Эту разницу во времени можно воспроизвести при запуске кода на моем MacBook M2 (разные цифры, но все равно большое расхождение). Я также попробовал time.time() и time.perf_counter() с теми же результатами.
Куда уходит все недостающее время и что я упустил?
Нет. RPi ничего не делает, кроме запуска этого кода (это 64-битная ОС Raspian без графического интерфейса), а M2 просто делает то, что обычно делает. Проблема в процессе itertools, но я понятия не имею, где и как.
Ваша программа сообщает мне, что это заняло 0,7 секунды, что далеко не 45, описанные в вашем посте. Попробуйте удалить asizeof
и т. д. и просто вывести команду «стоп-старт» или, возможно, запустить time python main.py
в bash.
Это не должно занять около 45 секунд. Что-то еще отнимает все время вашего процессора.
@user2357112 user2357112 Я согласен, но Pi является частью кластера и ничего не делает, кроме запуска этих фрагментов кода. В качестве еще одного теста я заменил строку комбо на: combos = ['a' for x in range(736281)]
, чтобы получить список аналогичного размера. Возвращает 0,2388 секунды и фактически работает в течение 5 секунд. Это реалистично.
...вы хотите сказать, что считаете расхождение между 0,2388 секунды и 5 секундами нормальным, а расхождение между 0,688 и 45 секундами нереальным?
Уберите asizeof.asizeof(combos)
и увидите, что все время проводится там...
Эффект, который вы наблюдаете, вызван рекурсивным вычислением общего размера созданного combos
, который вы используете в операторе печати, который также выводит разницу во времени, которую вы измерили и вычислили перед вызовом оператора print()
.
Таким образом, временная задержка, которую вы наблюдаете в ожидании распечатки результата сценарием, — это время, которое оператор print
тратит на оценку того, что ему нужно напечатать, когда измерение времени завершается перед запуском оператора print
.
Проверьте это сами и выньте asizeof.asizeof(combos)
из print()
, чтобы увидеть, что теперь измеренная и напечатанная разница во времени не сильно отличается от времени, пока вы не увидите результат на экране.
Другими словами:
Куда уходит все недостающее время и что я упустил?
Вы упустили из виду, что оператор print() требует времени, и все недостающее время ушло на вычисление общего размера combos
с использованием asizeof.asizeof(combos)
.
ОБРАТИТЕ ВНИМАНИЕ, что pympler — это модуль, написанный на чистом Python, и поэтому он очень медленно рекурсивно посещает все элементы комбо для расчета общего размера объекта комбо, где itertools, создавшие этот объект, представляют собой модуль, скомпилированный с C-кодом, и намного быстрее.
Спасибо. К счастью, этот процесс предназначен только для исследований и не окажет негативного влияния на мой проект.
Есть ли у вас что-то еще, создающее большую нагрузку на вашу систему?