Оптимизирует ли Python переменную, которая используется только как возвращаемое значение?
есть ли принципиальная разница между следующими двумя фрагментами кода? Первый присваивает значение переменной в функции, а затем возвращает эту переменную. Вторая функция просто возвращает значение напрямую.
превращает ли Python их в эквивалентный байт-код? Один из них быстрее?
корпус 1:
def func():
a = 42
return a
корпус 2:
def func():
return 42
2 ответа:
нет, это не.
компиляция в байтовый код CPython передается только через небольшой глазок оптимизатор который предназначен для выполнения только основных оптимизаций (см. test_peepholer.py в тестовом наборе для получения дополнительной информации об этих оптимизациях).
чтобы взглянуть на то, что на самом деле произойдет, используйте
dis
* для просмотра сгенерированных инструкций. Для первой функции, содержащей задание:from dis import dis dis(func) 2 0 LOAD_CONST 1 (42) 2 STORE_FAST 0 (a) 3 4 LOAD_FAST 0 (a) 6 RETURN_VALUE
в то время как, для второй функции:
dis(func2) 2 0 LOAD_CONST 1 (42) 2 RETURN_VALUE
в первой используются еще две (быстрые) инструкции:
STORE_FAST
иLOAD_FAST
. Они делают быстрый магазин и захватить значение вfastlocals
массив текущего кадра выполнения. Затем, в обоих случаях это. Итак, второе всегда так немного быстрее из-за меньшего количества команд, необходимых для выполнения.в общем, будьте в курсе что компилятор CPython-это консервативно в оптимизациях, которые он выполняет. Это не так и не пытается быть так же умны, как и другие компиляторы (которые, в общем, также имеют гораздо больше информации для работы). Основная цель дизайна, помимо очевидной правильности, заключается в том, чтобы а) сохранить его простым и б) быть как можно более быстрым при компиляции, чтобы вы даже не заметили, что существует фаза компиляции.
в конце концов, вы не должны утруждать себя маленькой вопросы как этот. Преимущество в скорости является крошечным, постоянным и, карликовым по сравнению с накладными расходами, введенными тем фактом, что Python интерпретируется.
*
dis
это небольшой модуль Python, который разбирает ваш код, вы можете использовать его, чтобы увидеть байт-код Python, который будет выполняться виртуальной машиной.Примечание: Как также указано в комментарии @Jorn Vernee, это специфично для реализации CPython Python. Другая реализация может сделать более агрессивные оптимизации, если они так хотят, CPython не делает.
оба в основном то же самое, за исключением того, что в первом случае объект
42
просто присваивается переменной с именемa
или, другими словами, имена (т. е.a
) см. значения (т. е.42
). Он не выполняет никаких назначений технически, в том смысле, что он никогда не копирует какие-либо данные.пока
return
ing, это называется bindinga
возвращается в первом случае, когда объект42
возвращается во втором случае.для больше чтения, см. эта замечательная статья Неда Батчелдера