C++ Скомпилировать код для всех вариантов конечного числа настроек
Например, внутри функции есть жесткая логика void Func(long param1, long param2, long param3, long param4, long param5)
,
У него много утверждений внутри, зависит от параметров, разные проверки, расчеты зависят от комбинаций и т. Д.
И эта функция вызывается много миллионов раз и занимает много времени на выполнение. И я хотел бы сократить это время.
Все параметры взяты из config.ini
файл, поэтому они неизвестны во время компиляции.
Но я знаю, что param1 может быть в диапазоне [1..3], param2 в диапазоне [0..1] и т. Д.
Итак, наконец, возможно, есть 200 комбинаций этих параметров.
И я хотел бы, чтобы мой компилятор разделил 200 комбинаций, и в начале выполнения, когда config.ini
загруженный, просто выберите один из них и избегайте вычисления зависимостей параметра во время выполнения.
Этого можно достичь в C++98? Или в C++11/14?
2 ответа
Конечно, это можно сделать с помощью шаблонов, поскольку шаблоны могут иметь целые числа вместо параметров типа. Например, следующая функция
template <int iParam1, int iParam2>
int sum()
{
return iParam1 + iParam2;
}
это функция, в которой iParam1
а также iParam2
являются фиксированными значениями для конкретного экземпляра шаблона. Например, функция sum<1, 2> - это функция, которая всегда возвращает 3
,
В вашем случае определите Func
с этим прототипом:
template <long Param1, long Param2, long Param3, long Param4, long Param5>
void Func()
Затем создайте std::map
который отображает комбинацию параметров в функцию, в которой эти параметры являются фиксированными. Что-то вроде этого:
using ParamCombination = std::tuple<long, long, long, long, long>;
using ParamsToFunction = std::pair < ParamCombination, std::function<void()> >;
std::map< ParamCombination, std::function<void()> > map =
{
ParamsToFunction(std::make_tuple<long, long, long, long, long>(1, 2, 2, 2, 2), Func<1, 2, 2, 2, 2>),
...
// This map will contain pairs of all possible parameter combinations
// and their corresponding functions. This is a long list but it can be
// easily generated using a script.
};
Эти функции будут иметь все преимущества оптимизации времени компиляции. Наконец, во время выполнения все, что вам нужно сделать, это создать кортеж, представляющий комбинацию параметров, и вызвать функцию, с которой этот кортеж сопоставляется:
auto comb = ParamCombination(1, 2, 2, 2, 2);
map[comb](); // function call
Я не знаю, рассматривали ли вы это, но вы могли бы загрузить конфигурацию в начале, рассчитать свои 200 возможных решений и поместить их в таблицу поиска. Это зависит от хранилища, которое вы можете сэкономить. Поскольку количество комбинаций кажется небольшим, это не должно быть проблемой. Вы просто объединяете параметр в целое число. Например ( x =[0...3]; y = [0...1]) => использовать первые 2 бита для x 3-го бита для y и так далее. Рассчитайте все возможности, используя циклы. И сохраните результат внутри массива. Если у вас нет параметра со степенью двойки. Вы можете просто умножить возможности. Например, x =[0...3] y =[0...5] z =[0...2] => idx = x + y*(возможно, x = 4) + z * (поз. X = 4) * (поз. У = 6)