Как создать "пустое условие if" в Python
Тема: Работает ли "пустое условие if" в Python и влияет ли это на производительность приложения?
В C довольно распространено использование такого "пустого" условия if
, например:
if(mostlyhappencondition)
; // пустое выражение
else {
dosomething();
}
Меня интересует, возможно ли использовать нечто подобное в Python? Сможем ли мы улучшить производительность приложения с помощью этого подхода, и почему?
4 ответ(ов)
В вашем вопросе рассматривается, как отсутствие ветки else
в условии if
может улучшить производительность, поскольку байт-коды не переходят к исполнению в случае if
.
Давайте посмотрим на пример функций и вывод команды dis.dis(foo)
.
Вот пример приложения:
def foo(x):
if x:
pass
else:
return x + 2
После дизассемблирования это выглядит так:
5 0 LOAD_FAST 0 (x)
3 POP_JUMP_IF_FALSE 9
6 6 JUMP_FORWARD 8 (to 17)
8 >> 9 LOAD_FAST 0 (x)
12 LOAD_CONST 1 (2)
15 BINARY_ADD
16 RETURN_VALUE
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
Как видно, во втором случае код переходит к ветке else
, которая обрабатывает возврат x + 2
только если if
не выполнено. Но после выполнения if
, интерпретатор всё равно выполняет LOAD_CONST
и RETURN_VALUE
, даже если if
сработал и вернулся None
.
Теперь рассмотрим следующую версию функции:
def foo(x):
if not x:
return x + 2
Дизассемблирование этого варианта показывает следующее:
11 0 LOAD_FAST 0 (x)
3 POP_JUMP_IF_TRUE 14
12 6 LOAD_FAST 0 (x)
9 LOAD_CONST 1 (2)
12 BINARY_ADD
13 RETURN_VALUE
>> 14 LOAD_CONST 0 (None)
Здесь интерпретатор выполняет POP_JUMP_IF_TRUE
, что позволяет избежать ненужного выполнения кода, если x
истинно. Это может привести к небольшому улучшению производительности, поскольку байт-код не выполняет лишние операции.
В заключение, действительно, наличие или отсутствие ветки else
в конструкции if
может повлиять на производительность, благодаря различиям в сгенерированном байт-коде.
Вы, похоже, ищете оператор pass
, который иногда необходим для создания пустого блока кода, чтобы избежать ошибки синтаксиса.
if mostlyhappencondition:
pass
else:
do_something()
Однако более привычным будет просто сделать так, что логически абсолютно эквивалентно:
if not mostlyhappencondition:
do_something()
Здесь нет никаких значительных преимуществ по производительности.
Если у вас нет недостатка в условии if True:
, вы можете использовать следующий подход:
if not mostlyhappenedcondition:
do something()
Если вам в будущем не нужно будет добавлять что-либо в блок if
, то использование такого условия стало бы избыточным в вашем коде.
В общем, старайтесь избегать лишних условий, поскольку это может усложнить чтение и понимание вашего кода.
Нет, это не улучшит производительность. На самом деле, в C тоже не дает прироста. Откуда вы это узнали?
Операторы not
/!
удобнее для чтения и должны работать с примерно одинаковой скоростью.
На самом деле, я протестировал это с помощью gcc -O4
:
#include <stdio.h>
int main(int argc, char *argv[]) {
for(int i = 0; i < 1000000000; i++) {
if(!(i < 900000000)) {
putchar('.');
}
}
}
и
#include <stdio.h>
int main(int argc, char *argv[]) {
for(int i = 0; i < 1000000000; i++) {
if(i < 900000000);
else {
putchar('.');
}
}
}
Программа #1 заняла 6.62 секунды, а программа #2 — 6.64 секунды на моем компьютере.
Однострочное выражение if-then-else
Стилизация многострочных условий в операторе 'if'? [закрыто]
Как протестировать несколько переменных на равенство одному значению?
if else в списковом включении
Как присвоить переменной значение в условии IF и вернуть её?