Сначала запишите его для удобства чтения. Лично я нахожу, что все подписки причиняют мне боль, поэтому я, вероятно, напишу это больше как:
for (i=0; i < a_len; i++) {
int val = a[i]; /* or whatever type */
int result = 0; /* default result */
if (val == 0) {
result = f1(val);
} else if (val % 2 == 0) {
result = f2(val);
}
a[i] = result;
}
Я предполагаю, что компилятор сгенерирует похожий код с оптимизацией. Но я не был бы шокирован, если один или другой был бы немного (только очень немного) лучше. И я бы поспорил, что если бы один был, это был бы тот, который использует местных жителей.
Кроме того, вы можете получить очень небольшое улучшение, изменив обход по массиву с помощью индекса на обход по нему с помощью указателя. Опять же, это очень зависит от компилятора и ситуации.
for (p=&a[0]; p < &a[a_len]; ++p) {
int val = *p; /* or whatever type */
int result = 0; /* default result */
if (val == 0) {
result = f1(val);
} else if (val % 2 == 0) {
result = f2(val);
}
*p = result;
}
И, да, я знаю, что это микрооптимизации, и вообще о них даже не стоит беспокоиться (пожалуйста, код для удобочитаемости и корректности ) - я просто указываю на некоторые варианты когда микрооптимизация может быть оправдана (эти предложения должны быть подкреплены анализом конкретной ситуации).
То, будет ли компилятор многократно перезагружаться из чего-то вроде [i] или нет, зависит от потока управления и от того, является ли объект, к которому осуществляется доступ, глобальным или его адрес был взят и передан другому объекту.
Если объект является глобальным или его адрес взят, и вы вызываете функцию, обычно компилятор должен предполагать, что объект мог быть изменен функцией, и ему придется перезагрузить его. Подобные проблемы возникают, когда указатели используются для передачи информации в функции. Использование locals может помочь смягчить эту проблему, так как компилятор может очень легко определить, что local не модифицируется вызываемой функцией, если не выбран адрес local. Компиляторы также могут попытаться решить эту проблему с помощью некоторой глобальной оптимизации (например, что делает MSVC во время соединения).
Ваш пример кода, вероятно, на самом деле не решает эту проблему, даже если массив a
является глобальным, потому что вы не перечитываете значение из массива после вызова одной из этих функций (вы пишете только в он).
Интересно, почему уценка убирает пустые строки из блоков в формате кода?