Есть ли разница между двумя следующими фрагментами кода? Первый присваивает значение переменной в функции, а затем возвращает эту переменную. Вторая функция просто возвращает значение напрямую.
Превращает ли Python их в эквивалентный байт-код? Один из них быстрее?
Случай 1 :
def func():
a = 42
return a
Случай 2 :
def func():
return 42
dis.dis(..)
оба, вы увидите, что есть разница , так что да. Но в большинстве реальных приложений накладные расходы по сравнению с задержкой обработки в функции не так велики.Ответы:
Нет, это не так .
Компиляция в байтовый код CPython проходит только через небольшой оптимизатор-глазок, который предназначен для выполнения только основных оптимизаций (см. Test_peepholer.py в наборе тестов для получения дополнительной информации об этих оптимизациях).
Чтобы
dis
увидеть, что на самом деле произойдет, используйте * для просмотра созданных инструкций. Для первой функции, содержащей присвоение:А для второй функции:
В первой используются еще две (быстрые) инструкции:
STORE_FAST
иLOAD_FAST
. Они позволяют быстро сохранить и получить значение вfastlocals
массиве текущего кадра выполнения. Затем в обоих случаяхRETURN_VALUE
выполняется а. Итак, второй работает немного быстрее из-за меньшего количества команд, необходимых для выполнения.В общем, имейте в виду, что компилятор CPython консервативен в оптимизации, которую он выполняет. Он не и не пытается быть таким же умным, как другие компиляторы (которые, как правило, также имеют гораздо больше информации для работы). Основная цель дизайна, помимо очевидной правильности, состоит в том, чтобы а) сохранить простоту и б) как можно быстрее скомпилировать их, чтобы вы даже не заметили, что существует фаза компиляции.
В конце концов, не стоит беспокоиться о таких мелких проблемах, как эта. Выигрыш в скорости крошечный, постоянный и превосходит накладные расходы, связанные с интерпретацией Python.
*
dis
- это небольшой модуль Python, который дизассемблирует ваш код, вы можете использовать его, чтобы увидеть байт-код Python, который будет выполнять виртуальная машина.Примечание. Как также указано в комментарии @Jorn Vernee, это относится к реализации Python в CPython. Другие реализации могут делать более агрессивные оптимизации, если они того пожелают, а CPython - нет.
источник
Оба в основном одинаковы, за исключением того, что в первом случае объект
42
просто присваивается переменной с именемa
или, другими словами, имена (т.е.a
) относятся к значениям (т.е.42
). Технически он не выполняет никаких назначений в том смысле, что никогда не копирует никаких данных.При
return
этом именованная привязкаa
возвращается в первом случае, а объект42
возвращается во втором случае.Для получения дополнительной информации обратитесь к этой замечательной статье Неда Батчелдера.
источник