Оптимизация условий оператора if

У меня есть оператор if с двумя условиями (разделенными оператором OR), одно из условий покрывает +70% ситуаций и занимает гораздо меньше времени для обработки / выполнения, чем второе условие, поэтому в интересах скорости я хочу только второе условие, которое должно быть обработано, если первое условие оценивается как ложное.

если я упорядочу условия так, чтобы первое условие (более быстрое) появилось в инструкции if первым - в тех случаях, когда это условие выполняется и оценивается как истинное, выполняется ли второе условие?

if ( (condition1) | (condition2) ){
  // do this
}

или мне нужно будет вложить два оператора if, чтобы проверять только второе условие, если первое оценивается как ложное?

if (condition1){
  // do this
}else if (condition2){
  // do this
}

Я работаю в PHP, однако я предполагаю, что это может быть языково-независимым.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
5
0
7 688
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Поскольку это не зависит от языка с тегами, я вмешаюсь. По крайней мере, для Perl первого варианта достаточно, я не знаком с PHP. Он оценивается слева направо и отключается, как только условие выполняется.

Практически каждый язык выполняет оценку короткого замыкания. Это означает, что второе условие оценивается только в том случае, если это абсолютно необходимо. Для этого в большинстве языков используется двойной канал ||, а не одинарный |.

См. http://en.wikipedia.org/wiki/Short-circuit_evaluation

На большинстве языков с приличной оптимизацией первый будет работать нормально.

Ответ принят как подходящий

Для языков C, C++, C#, Java и других языков .NET оптимизированы логические выражения, так что, как только известно достаточно, больше ничего не оценивается.

Старый трюк для создания обфусцированного кода заключался в использовании его для создания операторов if, например:

a || b();

если "a" истинно, "b ()" никогда не будет вычисляться, поэтому мы можем переписать его в:

if (!a)
    b();

и аналогично:

a && b();

станет

if (a)
    b();

Пожалуйста, обрати внимание, что это действительно только для || и оператор &&. Два оператора | и & является поразрядным или, и и, соответственно, и поэтому не "оптимизированы".

Обновлено: Как упоминалось другими, попытки оптимизировать код с использованием логики короткого замыкания очень редко тратятся с пользой.

Сначала сделайте ясность, потому что ее легче читать и понимать. Кроме того, если вы попытаетесь быть слишком умным, простая перестановка терминов может привести к совершенно разному поведению без какой-либо видимой причины.

Во-вторых, займитесь оптимизацией, но только после определения времени и профилирования. Слишком многие разработчики проводят преждевременную оптимизацию без профилирования. В большинстве случаев это совершенно бесполезно.

В последнее время я видел много таких вопросов - оптимизация до энной степени.

Я думаю, это имеет смысл при определенных обстоятельствах:

  1. Условие вычисления 2 не является операцией с постоянным временем
  2. Вы просите строго в образовательных целях - вы хотите знать, как работает язык, а не для экономии 3us.

В других случаях глупо беспокоиться о «самом быстром» способе итерации или проверки условия. Вместо написания тестов, которые требуют миллионов испытаний, чтобы увидеть любую записываемую (но незначительную) разницу, сосредоточьтесь на ясности.

Когда кто-то другой (может быть, вы!) Поднимет этот код через месяц или год, самое важное - это ясность.

В этом случае ваш первый пример короче, яснее и не требует повторения.

Согласно Эта статья 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

Я считаю и то и другое полезным.

Это именно то, что || и && do на большинстве других языков соответственно.

Arda Xi 12.06.2010 13:49

Короткое замыкание не для оптимизации. Его основная цель - избежать вызова кода, который не будет работать, но приведет к удобочитаемому тесту. Пример:

if (i < array.size() && array[i]==foo) ...

Обратите внимание, что array [i] вполне может получить нарушение прав доступа, если i находится вне допустимого диапазона, и приведет к сбою программы. Таким образом, эта программа, безусловно, зависит от короткого замыкания оценки!

Я считаю, что это причина написания выражений таким образом гораздо чаще, чем соображения оптимизации.

Другие вопросы по теме