Как создать "пустое условие 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 и вернуть её?