Можно ли оптимизировать серию «склеенных» std::function
и/или есть ли какая-либо реализация, которая пытается это сделать?
То, что я имею в виду, проще всего выразить математически: скажем, я хочу создать std::function
, являющееся функцией функции:
f(x,y,z) = x^2 * y^3 * z^4
g(x,y,z) = f(x,y,z) / (x*y^2)
Есть ли способ для разработчика STL/компилятора оптимизировать части арифметики, вызывающей объект функции g
, созданный из объекта функции f
?
Это было бы своего рода символическим упрощением функций, но поскольку это std::function
, его нужно было бы определить на машинном уровне.
Из-за того, что это оптимизация, которая требует времени и, вероятно, не бесплатна (в тактовых циклах и/или памяти), она, вероятно, не разрешена стандартом? Он очень близок к языку, который обычно запускается через виртуальную машину. (Я думаю, что LLVM больше, чем Java, с оптимизацией времени выполнения).
РЕДАКТИРОВАТЬ: Чтобы сделать обсуждение «более полезным», вот короткий фрагмент кода (я понимаю, что лямбда не является std::function
, но лямбда может быть сохранена в std::function
, поэтому, предполагая, что auto
ниже означает, что std::function<T>
с соответствующим T
будет выражать именно то, что я имел в виду выше):
auto f = [](const double x, const double y, const double z){ return x*x*y*y*y*z*z*z*z; };
auto g = [](const double c, const double y, const double z){ return f(x,y,z)/(x*y*y); };
«Тривиальный» компилятор сделал бы g
эквивалентным
double g(const double x, const double y, const double z){ return x*x*y*y*y*z*z*z*z/(x*y*y); }
В то время как оптимизированный std::function
мог бы это сделать (математически и во всех других смыслах правильно!):
double g( const double x, const double y, const double z){ return x*y*z*z*z*z; }
Обратите внимание, что хотя я говорю здесь о математических функциях, аналогичные преобразования можно было бы сделать для функций в общем смысле, но это потребует больше самоанализа, что означает накладные расходы.
Я вижу, что это очень важно при разработке математических и физических симуляций, где универсальность объединения существующих библиотечных функций в пользовательские функции со всеми обычными математическими упрощениями может стать хорошим методом выразительного, но производительного программного обеспечения для вычислений.
volatile
, в частности, но не для кода, о котором вы спрашиваете.) Возможно, это больше вопрос о том, может ли компилятор безопасно выполнить оптимизацию, и стоит ли разработчикам компилятора тратить время на это. искать оптимизацию. - person Jonathan Leffler   schedule 21.07.2011constexpr
. - person Richard   schedule 21.07.2011g(0,y,z) = 0
, потому что вы больше не делите на 0 (!). Это было своего рода моей точкой зрения с этими оптимизациями, своего рода математическим упрощением, если хотите... - person rubenvb   schedule 21.07.2011std::function
(и c++0x). Вам нужно показать код, чтобы сделать обсуждение полезным. - person Gene Bushuyev   schedule 21.07.2011x/x = 1
только тогда, когдаx
не равно нулю. Что верно, так это то, что функцияx -> x/x
имеет устранимую сингулярность в 0 с пределом 1. - person Kerrek SB   schedule 21.07.20111/x
только в том случае, еслиx
не равно 0, ноx/x
так же хорош, как и все, даже когда x = 0, потому что пределx/x
для x-›0 равен все еще четко определена, и функция непрерывна и гладка, как вы можете найти... - person rubenvb   schedule 22.07.2011std::function
из вашего вопроса не только потому, что лямбда неstd::function
, но и потому, что сложности для компилятора, использующегоstd::function
, делают ответ определенным НЕТ. И даже использование лямбда-выражений является ненужным усложнением. Самый простой способ — написать две встроенные функции. - person Gene Bushuyev   schedule 22.07.2011std::function
для передачи лямбда почти неизбежно, под чем я подразумеваю, что алгебраическая система не будет использовать одно без другого и должна иметь возможность оптимизировать оба. Нигде в стандарте не говорится, что лямбда не может бытьstd::function
, просто в некоторых случаях это сложно (захват переменных), но никогда не запрещается. Я бы даже сказал, воодушевлен, видя, что лямбда должна быть преобразована вstd::function
. - person rubenvb   schedule 22.07.2011std::function
будет неизбежен, является полным отвлекающим маневром: использование функцииmain
также неизбежно, но последнее место, где следует искать оптимизацию в вашем сценарии, находится вmain
. Алгебраическая система определенно не хотела бы использоватьstd::function
, поскольку стирание типов избавляет от важной информации (как следует из названия, типов); client-code будет использовать его, но не library-code. - person Luc Danton   schedule 22.07.2011