Будет ли современный компилятор автоматически оптимизировать следующий код C ++? - PullRequest
2 голосов
/ 20 февраля 2012

Если я буду использовать следующие коды, будет ли компилятор оптимизировать его как структуру переключателя, которая использует двоичное дерево для поиска значений?

   if ( X == "aaaa" || X == "bbbb" || X == "cccc" || X == "dddd" )
   {

   }
   else if ( X == "abcd" || X == "cdef" || X == "qqqq" )
   {

   }

Это всего лишь пример, нет никакой картины того, что находится внутрисимвол кавычки

ОБНОВЛЕНИЕ

Хорошо, X - это строка, но я не думаю, что здесь это имеет значение, я просто хочу знать, когда все внутриif это все о единственной переменной, будет ли она оптимизирована.

Ответы [ 4 ]

3 голосов
/ 20 февраля 2012

Значения будут сравниваться одно за другим, так как это требуется для || или оператора короткого замыкания. Итак, здесь произойдут две вещи:

  • X будет сравниваться один за другим справа налево.
  • После любого успешного сравнения не будет НИКАКОГО сравнения (так как это оператор короткого замыкания ИЛИ), т.е. в следующем случае

Например:

int hello() {
    std::cout<<"Hello";
    return 10;
}

int world() {
    std::cout<<"World";
    return 11;
}

int hello2() {
    std::cout<<"Hello2";
    return 9;
}

int a = 10;

bool dec = (a == hello() || a == world())
bool dec = (a == hello2() || a == hello() || a == world())

Выход для первого оператора будет:

Hello

как a == world() не будет выполнен, а для второго Hello2 Hello, поскольку сравнения продолжаются до первого успеха.

В случае оператора && сравнения продолжаются до первого сбоя (поскольку этого достаточно для определения результата всего оператора).

1 голос
/ 20 февраля 2012

Почти наверняка нет.Бинарный поиск требует определенного порядка отношений и умения сравнивать меньше.Компилятор не может предположить, что такое существует, и даже если он найдет его, он не может предположить, что он определяет отношение эквивалентности, которое соответствует ==.Также возможно, что компилятор не может определить, что функция, определяющая отношение порядка, не имеет побочных эффектов.(Если он имеет побочные эффекты или если какая-либо операция в выражении имеет побочные эффекты, компилятор должен учитывать поведение короткого замыкания ||.) Наконец, даже если компилятор сделал все это ... что произойдет, если я тщательно выбралпорядок сравнений, так что наиболее частый случай - первый.Такая «оптимизация» может даже оказаться пессимизацией.

«Правильно» справиться с этим - создать карту, отображающую строки в указатели на функции (или на полиморфные функциональные объекты, если какое-то состояниеучастие).

1 голос
/ 20 февраля 2012

Вероятно, это зависит от установленных вами флагов. Двоичные деревья быстрее для поиска, но обычно требуют больше кода для обработки. Так что, если вы оптимизировали по размеру, это, вероятно, не будет. Я не уверен, будет ли это так или иначе. Вы знаете, gcc оптимизирован в соответствии с большим количеством флагов. O1, O2, O3, O4 - это просто простые формы для обозначения больших групп флагов. Вы можете найти список всех флагов оптимизации здесь: http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Попробуйте найти на этой странице строки, двоичные деревья и т. Д.

0 голосов
/ 20 февраля 2012

Лучший способ проверить это - пример, приведенный ниже.

int a = 0;
int b = 0;
if(a == a || b++) {
    ...
}
cout << b;

значение переменной b должно быть 0 в конце.b++ часть не будет выполнена.это ожидаемое поведение, но могут быть некоторые исключения в зависимости от компилятора и его настроек оптимизации.даже многие скриптовые языки вроде JavaScript ведут себя так.

...