У меня есть оператор if с двумя условиями (разделенными оператором OR), одно из условий покрывает +70% ситуаций и занимает гораздо меньше времени для обработки / выполнения, чем второе условие, поэтому в интересах скорости я хочу только второе условие, которое должно быть обработано, если первое условие оценивается как ложное.
если я упорядочу условия так, чтобы первое условие (более быстрое) появилось в инструкции if первым - в тех случаях, когда это условие выполняется и оценивается как истинное, выполняется ли второе условие?
if ( (condition1) | (condition2) ){
// do this
}
или мне нужно будет вложить два оператора if, чтобы проверять только второе условие, если первое оценивается как ложное?
if (condition1){
// do this
}else if (condition2){
// do this
}
Я работаю в PHP, однако я предполагаю, что это может быть языково-независимым.






Поскольку это не зависит от языка с тегами, я вмешаюсь. По крайней мере, для Perl первого варианта достаточно, я не знаком с PHP. Он оценивается слева направо и отключается, как только условие выполняется.
Практически каждый язык выполняет оценку короткого замыкания. Это означает, что второе условие оценивается только в том случае, если это абсолютно необходимо. Для этого в большинстве языков используется двойной канал ||, а не одинарный |.
На большинстве языков с приличной оптимизацией первый будет работать нормально.
Для языков C, C++, C#, Java и других языков .NET оптимизированы логические выражения, так что, как только известно достаточно, больше ничего не оценивается.
Старый трюк для создания обфусцированного кода заключался в использовании его для создания операторов if, например:
a || b();
если "a" истинно, "b ()" никогда не будет вычисляться, поэтому мы можем переписать его в:
if (!a)
b();
и аналогично:
a && b();
станет
if (a)
b();
Пожалуйста, обрати внимание, что это действительно только для || и оператор &&. Два оператора | и & является поразрядным или, и и, соответственно, и поэтому не "оптимизированы".
Обновлено: Как упоминалось другими, попытки оптимизировать код с использованием логики короткого замыкания очень редко тратятся с пользой.
Сначала сделайте ясность, потому что ее легче читать и понимать. Кроме того, если вы попытаетесь быть слишком умным, простая перестановка терминов может привести к совершенно разному поведению без какой-либо видимой причины.
Во-вторых, займитесь оптимизацией, но только после определения времени и профилирования. Слишком многие разработчики проводят преждевременную оптимизацию без профилирования. В большинстве случаев это совершенно бесполезно.
В последнее время я видел много таких вопросов - оптимизация до энной степени.
Я думаю, это имеет смысл при определенных обстоятельствах:
В других случаях глупо беспокоиться о «самом быстром» способе итерации или проверки условия. Вместо написания тестов, которые требуют миллионов испытаний, чтобы увидеть любую записываемую (но незначительную) разницу, сосредоточьтесь на ясности.
Когда кто-то другой (может быть, вы!) Поднимет этот код через месяц или год, самое важное - это ясность.
В этом случае ваш первый пример короче, яснее и не требует повторения.
Согласно Эта статья PHP выполняет оценку короткого замыкания, что означает, что если выполняется первое условие, второе даже не оценивается. Также довольно легко протестировать (из статьи):
<?php
/* ch06ex07 – shows no output because of short circuit evaluation */
if (true || $intVal = 5) // short circuits after true
{
echo $intVal; // will be empty because the assignment never took place
}
?>
В C, C++ и Java утверждение:
if (condition1 | condition2) {
...
}
будет оценивать оба условия каждый раз и будет истинным только в том случае, если истинно все выражение.
Заявление:
if (condition1 || condition2) {
...
}
будет оценивать condition2, только если condition1 ложно. Разница значительна, если condition2 является функцией или другим выражением с побочным эффектом.
Однако нет никакой разницы между корпусом || и корпусом if / else.
| - это побитовый оператор в PHP. Это точно не означает $a OR $b. Вы захотите использовать двойную трубу. И да, как уже упоминалось, PHP выполняет оценку короткого замыкания. Аналогичным образом, если первое условие предложения && оценивается как ложное, PHP также не оценивает остальную часть предложения.
Хотя использование короткого замыкания в целях оптимизации часто является излишним, безусловно, есть и другие веские причины для его использования. Один из таких примеров (на C++) следующий:
if ( pObj != NULL && *pObj == "username" ) {
// Do something...
}
Здесь короткое замыкание используется для обеспечения того, чтобы pObj был назначен до его разыменования. Это гораздо более кратко, чем наличие вложенных операторов if.
На VB.net есть два замечательных выражения: «OrElse» и «AndAlso».
OrElse выполнит короткое замыкание при первом достижении оценки True и выполнит желаемый код.
If FirstName = "Luke" OrElse FirstName = "Darth" Then
Console.Writeline "Greetings Exalted One!"
End If
AndAlso замкнет себя в первый раз при оценке False и не оценит код в блоке.
If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
Console.Writeline "You are the one and only."
End If
Я считаю и то и другое полезным.
Короткое замыкание не для оптимизации. Его основная цель - избежать вызова кода, который не будет работать, но приведет к удобочитаемому тесту. Пример:
if (i < array.size() && array[i]==foo) ...
Обратите внимание, что array [i] вполне может получить нарушение прав доступа, если i находится вне допустимого диапазона, и приведет к сбою программы. Таким образом, эта программа, безусловно, зависит от короткого замыкания оценки!
Я считаю, что это причина написания выражений таким образом гораздо чаще, чем соображения оптимизации.
Это именно то, что || и && do на большинстве других языков соответственно.