Компиляторная оптимизация C++ передаваемых аргументов

Альтернативой обратным вызовам (которые полностью действительны) являются обещания, которые на самом деле являются просто другой формой или обратными вызовами. Предполагая, что вы используете $ .get jQuery, вы уже используете Promises:

getInstructionType(applicationNumber, function(result) {
  return getInstructionValidationResult(applicationNumber)
    .then(function() {
      setValidationRowColor(result)
    })
});

function getInstructionValidationResult(applicationNumber) {
  var url = //-snip-;
  return $.get(url)
}

function getInstructionType(applicationNumber) {
  var url = //-snip-;
  return $.get(url)
}

Обратите внимание, что все, что я сделал, это return $.get и добавил .then, который принимает ваш обратный вызов getInstructionType

9
задан cdleary 12 November 2008 в 00:13
поделиться

5 ответов

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

То, в чем Вы нуждаетесь, должно переименовать Вашу функцию к WARN2 и добавьте макрос что-то как:

#define WARN(s) do {if (WARNINGS_ENABLED) WARN2(s);} while (false)

Это предотвратит оценку s во времени выполнения, если Вам не включили предупреждения.

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

12
ответ дан 4 December 2019 в 10:34
поделиться

Можно проверить то, что GCC/G ++ делают при помощи-S опции. Это произведет код, прежде чем он на самом деле будет собран – см. gcc (1).

GCC и G ++ более или менее ведут себя то же в этом случае. Таким образом, я сначала перевел код в C для создания некоторых дальнейших тестов:

char WARNINGS_ENABLED = 0;

inline void WARN(const char* message) {
    if (!WARNINGS_ENABLED) {
        return;
    }
    puts(message);
}

int main() {
    WARN("foo");
    return 0;
}

выполненный gcc-O3-S file.c и изучает выходной файл 'file.s'
Вы будете видеть, что GCC ничего не удалил!

Это не то, что Вы попросили, а чтобы дать компилятору возможность оптимизировать тот код, необходимо будет сделать константу WARNINGS_ENABLED. Альтернатива должна сделать это статичным и не изменяющимся значение в том файле. Но: создание его статичный имеет побочный эффект, что символ не экспортируется.

static const char WARNINGS_ENABLED = 0;

inline void WARN(const char* message) {
  if (!WARNINGS_ENABLED) {
      return;
  }
  puts(message);
}

int main() {
    WARN("foo");
    return 0;
}

GCC затем полностью очищает код.

6
ответ дан 4 December 2019 в 10:34
поделиться

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

Я не эксперт по повышению, но я предполагаю, что существует способ создать лямбду, которая будет только оценена для генерации строки, если WARNINGS_ENABLED будет верен. Что-то как...

inline void warnFunc(some_boost_lambda &message_generator) {
  if (WARNINGS_ENABLED) {
    cerr << message_generator() << endl;
  }
}

#define WARN(msg) warnFunc(...insert boost magic here to turn msg into a lambda...)
1
ответ дан 4 December 2019 в 10:34
поделиться

Нет, компилятор не должен оптимизировать код в любом случае, если глобальный WARNING_ENABLED не объявляется константой.

BTW, если ПРЕДУПРЕЖДАЮТ, является подставляемой функцией, Вы все еще заплатите цену на конструкцию сообщения (который очень неэффективен в Вашем примере с lexical_cast и оператором + на строках), даже если это отключено.

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

1
ответ дан 4 December 2019 в 10:34
поделиться

Вы не можете только определить все это использование препроцессора?

void inline void LogWarning(const string &message) 
{
  //Warning
}

#ifdef WARNINGS_ENABLED
#define WARN(a) LogWarning(a)
#else
#define WARN(a)
#endif

Это, как УТВЕРЖДЕНИЕ () макрос работает. Весь код в скобках в, ДАЖЕ ПРЕДУПРЕЖДАЕТ не делает его через препроцессор к компилятору. Это означает, что можно сделать другой материал как

#ifdef WARNINGS_ENABLED
// Extra setup for warning
#endif
//....
WARN(uses setup variables)

И это скомпилирует оба пути.

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

0
ответ дан 4 December 2019 в 10:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: