Я не знаком с деталями того, как операторы сложения и умножения определяются в C ++, и я также не знаю, какая информация доступна или не доступна компилятору для оптимизации неэффективных порядков работы.
Допустим, у нас есть матричный тип данных с реализацией поэлементного умножения на скаляр (т.е. масштабирование матрицы скаляром). Если у нас есть следующий фрагмент кода:
Matrix a;
float b = /* value set at runtime */;
float c = /* value set at runtime */;
a = a * b * c;
Если бы мы наивно оценивали это выражение слева направо, мы бы сначала масштабировали a
от b
а затем масштабировать его по c
а не масштабирование a
продуктом b
а также c
, Может ли компилятор выбрать последний
(более эффективное) поведение вместо прежнего?
Некоторые эксперименты с Godbolt показывают, что последние версии GCC и Clang генерируют один и тот же код для a * b * c
как это делается для (a * b) * c
, который длиннее, чем он генерирует для a * (b * c)
поэтому, похоже, что нет, компиляторы недостаточно умны, чтобы выполнять оптимизацию, о которой вы спрашиваете.
Вы могли бы просто заключить в скобки b * c
сам. Более сложное решение — иметь *
оператор генерирует шаблон выражения, который будет оптимизирован перед оценкой, поэтому даже если пользователь вводит (a * b) * c
ваша библиотека переставит его в a * (b * c)
прежде чем оценивать это.
Других решений пока нет …