В чем разница между операторами IF, CASE и WHILE? - PullRequest
2 голосов
/ 24 декабря 2009

Я просто хочу знать, в чем разница между всеми условными утверждениями в target-c и тем, что быстрее и легче.

Ответы [ 10 ]

13 голосов
/ 24 декабря 2009

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

9 голосов
/ 24 декабря 2009

If и case описано

В то время как заявление описано

Поскольку эти заявления делают разные вещи, спорить о том, что быстрее, непродуктивно.

Это все равно, что спросить, быстрее ли молоток, чем отвертка.

5 голосов
/ 24 декабря 2009

Не зависящая от языка версия (в основном, очевидно, это не считается для декларативных или других странных языков):

Когда I преподавали программирование (довольно давно, я буду свободно признавать), язык состоял из трех способов выполнения инструкций:

  • последовательность (все по порядку).
  • выбор (делая одно из многих).
  • итерация (выполнение чего-либо ноль или более раз).

Операторы if и case являются вариантами выбора. If используется для выбора одного из двух различных параметров в зависимости от условия (с использованием псевдокода):

if condition:
    do option 1
else:
    do option 2

с учетом того, что else может не понадобиться, в этом случае он фактически else do nothing. Также помните, что опция 1 или 2 может также состоять из любого из типов операторов, включая больше if операторов (называемых вложением).

Case немного отличается - обычно он предназначен для более чем двух вариантов, например, когда вы хотите делать разные вещи на основе персонажа:

select ch:
    case 'a','e','i','o','u':
        print "is a vowel"
    case 'y':
        print "never quite sure"
    default:
        print "is a consonant"

Обратите внимание, что вы можете использовать case для двух вариантов (или даже одного), но это немного похоже на убийство мухи с помощью термоядерной боеголовки.

While не вариант выбора, а итерационный. Он относится к for, repeat, until и множеству других возможностей.

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

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

Языковые конструкции, такие как if, while, case и т. Д., Уже будут настолько быстрыми, насколько это возможно, поскольку они интенсивно используются и относительно просты. Сначала вы должны писать код для удобства чтения и беспокоиться о производительности только тогда, когда это становится проблемой (см. YAGNI).

Даже если вы обнаружите, что использование if/goto комбинаций вместо case позволяет вам работать немного быстрее, результирующая болтовня исходного кода будет сложнее поддерживать в нужном направлении.

1 голос
/ 24 декабря 2009

Вы спрашиваете, будет ли структура if выполняться быстрее, чем инструкция switch внутри большого цикла? Если это так, я собрал быструю проверку, этот код был помещен в метод viewDidLoad нового проекта на основе представления, который я только что создал в последнем Xcode и iPhone SDK:

NSLog(@"Begin loop");
NSDate *loopBegin = [NSDate date];

int ctr0, ctr1, ctr2, ctr3, moddedNumber;
ctr0 = 0;
ctr1 = 0;
ctr2 = 0;
ctr3 = 0;
for (int i = 0; i < 10000000; i++) {
    moddedNumber = i % 4;

    // 3.34, 1.23s in simulator
    if (moddedNumber == 0)
    {
        ctr0++;
    }
    else if (moddedNumber == 1)
    {
        ctr1++;
    }
    else if (moddedNumber == 2)
    {
        ctr2++;
    }
    else if (moddedNumber == 3)
    {
        ctr3++;
    }

    // 4.11, 1.34s on iPod Touch
    /*switch (moddedNumber)
    {
        case 0:
            ctr0++;
            break;
        case 1:
            ctr1++;
            break;
        case 2:
            ctr2++;
            break;
        case 3:
            ctr3++;
            break;
    }*/
}

NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceDate:loopBegin];

NSLog(@"End loop: %f seconds", elapsed );

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

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

1 голос
/ 24 декабря 2009

Каждый оператор условия служит разным целям, и вы не будете использовать его в каждой ситуации. Узнайте, какие из них подходят для какой ситуации, а затем напишите свой код. Если вы профилируете свой код и обнаружите, что есть узкое место, тогда вы решите его. Не беспокойтесь об оптимизации, пока не возникнет проблема.

1 голос
/ 24 декабря 2009

регистр может быть записан как

if (a)
{
    // Do something
}
else if (b)
{
    // Do something else
}

Но случай гораздо эффективнее, поскольку он оценивает условное выражение только один раз, а затем ответвляется.

while полезно только в том случае, если вы хотите, чтобы условие оценивалось и соответствующий кодовый блок выполнялся несколько раз. Если вы ожидаете, что условие произойдет только один раз, тогда оно эквивалентно if. Более удачное сравнение состоит в том, что while является более обобщенным for.

1 голос
/ 24 декабря 2009

пока не условно это цикл. Разница в том, что тело цикла while может быть выполнено много раз, тело условия будет выполнено только один раз или не выполнено вовсе.

Разница между if и switch заключается в том, что if принимает произвольное выражение в качестве условия, а switch просто принимает значения для сравнения. По сути, если у вас есть такая конструкция, как if(x==0) {} else if(x==1) {} else if(x==2) ..., ее можно написать гораздо более кратко (и эффективно) с помощью switch.

0 голосов
/ 24 декабря 2009

Я только что вспомнил самое важное об условных кодах и коде ветвления . Закажите свой код следующим образом

if(x==1); //80% of the time
else if(x==2); // 10% of the time
else if(x==3); //6% of the time
else break;

Вы должны использовать последовательность else ... и в этом случае логика прогнозирования в вашем ЦП будет правильно предсказывать для x==1 и избегать прерывания вашего конвейера для 80% всего выполнения.

Дополнительная информация от Intel. В частности:

Чтобы эффективно написать свой код для использования этих правил, при написании операторов if-else или switch сначала проверьте наиболее распространенные случаи и постепенно переходите к наименее распространенным. Циклы не обязательно требуют какого-либо специального упорядочения кода для статического предсказания ветвления, поскольку обычно используется только условие итератора цикла.

Следуя это правило вы утончаются дают подсказку CPU о том, как предвзятости логики предсказания к вашему прикованному условным.

0 голосов
/ 24 декабря 2009

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

Шмоопти сказал: «Поскольку эти заявления делают разные вещи, спорить о том, что быстрее, бессмысленно».

Ну ... это может быть плохо проведенное время, но это не бессмысленно . Например, допустим, у вас есть оператор if:

if (cond) {
    code
}

Вы можете преобразовать это в цикл, который выполняется не более одного раза:

while (cond) {
    code
    break;
}

Последний будет работать медленнее практически на любом языке (или с той же скоростью, потому что оптимизатор превратил его обратно в оригинальный if за кадром!) Тем не менее, в компьютерном программировании бывают случаи, когда (из-за странных обстоятельств ) запутанная вещь работает быстрее

Но эти инциденты редки. Внимание должно быть сосредоточено на вашем коде - что делает его понятным и что отражает ваши намерения.

0 голосов
/ 24 декабря 2009

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

Я предлагаю вам иди сюда для всех ваших потребностей оптимизации. Руководства написаны для программиста в стиле c и относительно просты для понимания, если вы знаете какую-то сборку. Эти руководства должны объяснить вам тонкости современных процессоров, стратегии, используемые топовыми компиляторами, и лучший способ структурировать код, чтобы извлечь из него максимальную пользу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...