Я оцениваю выражение, 6^6^6
используя python
и bc
отдельно.
Содержимое файла python есть print 6**6**6
. Когда я выполняю time python test.py
, я получаю вывод как
real 0m0.067s
user 0m0.050s
sys 0m0.011s
И затем я выполнил команду, time echo 6^6^6 | bc
которая дала мне следующий вывод
real 0m0.205s
user 0m0.197s
sys 0m0.005s
Из этих результатов ясно, что системное время, используемое python и bc, составляло 11 мс и 5 мс соответственно. Команда bc превзошла python на уровне системного времени, но когда дело доходит до пользователя и реального времени, python был почти в 4 раза быстрее, чем bc . Что могло быть там. Я не дал никакого приоритета процессам как таковым. Я пытаюсь понять эту ситуацию.
python
performance
process-management
bc
ganessh
источник
источник
echo | bc
включает в себя запуск подоболочки из-за конвейера - вот откуда, вероятно, пришло ваше дополнительное пользовательское время. Чтобы сделать это справедливым тестом, скрипт python должен читать из stdin, чтобы вы моглиtime echo 6**6**6 | whatever.py
.echo 6^6^6 | time bc
.6**6**6
выражение фактически вычисляется во время компиляции . Однако, поскольку вы запускаете файл напрямую, а не импортируете его из модуля, это не должно иметь значения. Чтобы увидеть разницу10**12345678
вa.py
файле и попытаться импортировать его из интерактивного интерпретатора. Затем закройте интерпретатор, перезапустите его и импортируйтеa
снова. В первый раз это должно занять заметное количество времени (потому что python компилирует модуль), в то время как во второй раз он загружает тот.pyc
, который должен быть мгновенным,Ответы:
Python импортирует большое количество файлов при запуске:
Каждый из них требует еще большего количества попыток открыть файл Python, потому что существует много способов определить модуль:
Каждая «попытка», за исключением встроенных, требует системных вызовов / системных вызовов, и каждый «импорт» вызывает около 8 «попыток» сообщений. (Существовали способы уменьшить это с помощью zipimport, и для каждого пути в PYTHONPATH может потребоваться еще один вызов.)
Это означает, что на моем компьютере Python запускается почти 200 системных вызовов, и «time» назначает это «sys», а не «user», потому что пользовательская программа ожидает выполнения каких-либо действий в системе.
Для сравнения, и, как сказал Тердон, «bc» не имеет такой высокой стоимости стартапа. Глядя на вывод dtruss (у меня Mac; «strace» для ОС на базе Linux), я вижу, что bc не выполняет никаких системных вызовов open () или stat (), за исключением загрузки нескольких общих библиотеки - это начало, что, конечно, делает и Python. Кроме того, у Python есть больше файлов для чтения, прежде чем он будет готов что-либо обрабатывать.
Ожидание диска идет медленно.
Вы можете понять стоимость запуска Python, выполнив:
На моем аппарате это 0,032 с, в то время как «печать 6 ** 6 ** 6» составляет 0,072 с, поэтому начальная стоимость составляет 1/2 от общего времени, а расчет + преобразование в десятичное число составляет другую половину. В то время как:
занимает 0,005 с, а "6 ^ 6 ^ 6" - 0,184 с, поэтому возведение в bc более чем в 4 раза медленнее, чем в Python, даже несмотря на то, что начало в 7 раз быстрее.
источник
Я нашел хороший ответ на SO, объясняющий различные поля:
Итак, в вашем конкретном примере версия Python быстрее с точки зрения фактического времени, которое требуется для завершения. Тем не менее, подход python тратит больше времени в пространстве ядра, вызывая функции ядра. Команда
bc
практически не тратит время в пространстве ядра и все свое время проводит в пространстве пользователя, предположительно выполняя внутреннийbc
код.Для вас это не имеет значения, единственная информация, которая вас действительно волнует, -
real
это фактическое время, прошедшее между запуском команды и ее выводом.Вы также должны знать, что эти крошечные различия нестабильны, они также будут зависеть от загрузки вашей системы и будут меняться при каждом запуске команды:
источник
Я объясню это с другой точки зрения.
Честно говоря,
bc
имеет преимущество, поскольку ему не нужно ничего читать с диска, а нужны только его двоичные объекты / двоичные файлы, в то время как python должен импортировать серию модулей + чтение файла. Таким образом, ваш тест может быть смещен в сторонуbc
. Чтобы действительно проверить это, вы должны использоватьbc -q file
гдеfile
содержит:Изменение только того, что изменило время использования
echo
:Чтобы использовать файл:
(вам придется использовать метод Тердона, чтобы заметить большие различия, но, по крайней мере, мы знаем, что они есть)
Теперь, с точки зрения python, python должен читать с диска, компилировать и выполнять каждый раз файл, а также загружать модули как точки Эндрю , что замедляет время выполнения. Если вы скомпилируете байт-код скрипта Python, вы заметите, что на выполнение кода уходит на 50% меньше времени:
компилируется:
Как видите, существует несколько факторов, которые могут повлиять на время выполнения между различными инструментами.
источник
Я имел преимущество читать другие ответы. Во-первых, такие люди, как я, должны знать причину, по которой мы имеем дело с таким огромным целым числом, заключается в том, что оба
Python
иbc
выполняют расширение правой степени ассоциативного возведения в степень, что означает, что это не6^36
мы оцениваем, а6^46656
значительно больше. 1Используя варианты следующих команд, мы можем извлечь среднее значение для конкретного элемента вывода как
time
зарезервированного слова, так и команды:Можно пойти другим путем и полностью удалить файл из сравнения. Кроме того, мы можем сравнить синхронизацию bc с чем-то вроде
dc
команды, поскольку исторически первый является «процессором переднего плана» для второго. Следующие команды были рассчитаны по времени:Обратите внимание, что
dc
команда является левой ассоциативной для возведения в степень. 2У нас есть некоторые результаты с
time
(bash) для 1000 итераций (в секундах):bc
иdc
предложить сопоставимую производительность в этом контексте.Менее точные 3 результата из команды
/usr/bin/time
GNUtime
(точность масштаба здесь недопустима, но результаты аналогичны):Преимущество
/usr/bin/time
заключается в том, что он предлагает-v
опцию, которая дает гораздо больше информации, которая может быть полезна в конечном итоге.Можно также оценить это внутренне, так сказать с
timeit
модулем Python:Это немного быстрее, чем мы видели раньше. Давайте попробуем сам переводчик:
Это самое быстрое, что я видел.
Если мы оценим как меньшее возведение в степень
6^6
, то команда time дает удивительные результаты - используя те же самыеfor
команды цикла, которые мы использовали, мы теперь имеем:Так что с меньшим целым числом
bc
вдруг намного быстрее ?? От перезагрузки системы до второго запуска не имеет значения. В то же время, если мы используемtimeit
Python, мы получаем:Это микросекунды , а не миллисекунды, так что это не совпадает с гораздо более медленными результатами при использовании
for
цикла. Возможно, для дальнейшего тестирования требуются другие инструменты, и, как другие объясняли, здесь есть нечто большее, чем кажется на первый взгляд. Кажется, Python был быстрее в сценарии вопроса, но не ясно, можно ли сделать выводы за этим ...1. Излишне говорить , что это выходит за рамки чего - то вроде эха арифметического расширения , т.е.
echo $((6**6**6))
-bash
также случается правоассоциативной для этого есть6^6^6 = 6^(6^6)
.2. Сравните с этим:
6 6 ^ 6 ^ p
.3. Возможно, команда GNU time предоставляет больше информации при запуске в BSD UNIX (документ информации о времени GNU): большая часть информации, отображаемой в «time», получена из системного вызова «wait3». Числа такие же хорошие, как и те, что возвращены функцией wait3. Многие системы не измеряют все ресурсы, о которых может сообщать «время»; эти ресурсы указаны как ноль. Системы, которые измеряют большинство или все ресурсы, основаны на 4.2 или 4.3BSD. Более поздние выпуски BSD используют другой код управления памятью, который измеряет меньше ресурсов. - В системах, в которых нет вызова «wait3», который возвращает информацию о состоянии, вместо этого используется системный вызов «times». Он предоставляет гораздо меньше информации, чем «wait3», поэтому в «системном времени» этих систем большинство ресурсов указывается как ноль.
источник