Search code examples
c++architecturestatic-compilation

C++ Compile code for all variants of finite number of settings


For example, there is hard logic inside function void Func(long param1, long param2, long param3, long param4, long param5).

It has a lot of statements inside depends on parameters, different checks, calculations depends on combinations and etc.

And that function is called many million times and takes serious amount of execution time. And I'd like to reduce that time.

All parameters are taken from config.ini file, so, they are unknown at compile time.

But I know, that param1 may be in diapason [1..3], param2 in diapason [0..1] and etc.

So, finally, there is maybe 200 combinations of those parameters.

And I'd like my compiler compile separated 200 combination, and at the beginning of run-time, when config.ini loaded, just choose one of them, and avoid run-time calculation of parameter's dependencies.

Is that possible to achieve in C++98? Or in C++11/14?


Solution

  • It is certainly possible to do this using templates, since templates can have integers instead of type parameters. For instance, the following function

    template <int iParam1, int iParam2>
    int sum()
    {
        return iParam1 + iParam2;
    }
    

    is a function in which iParam1 and iParam2 are fixed values for a specific template instantiation. For example, function sum<1, 2> is a function that always returns 3.

    In you case, define Func with this prototype:

    template <long Param1, long Param2, long Param3, long Param4, long Param5>
    void Func()
    

    Then, create a std::map that maps a combination of parameters to a function in which these parameters are fixed. Something like this:

    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.    
    };
    

    These function will have all the benefits of compile time optimizations. Finally, during runtime, all you need to do is create a tuple that represents a parameter combination and call the function that this tuple maps to:

    auto comb = ParamCombination(1, 2, 2, 2, 2);
    map[comb](); // function call