c++ - 采用 N 个参数并返回 N 个值的高性能解决方案

标签 c++ performance templates c++11 variadic-templates

我可以使用什么来使函数接受 N 个参数,其中 N 在编程时未知但在编译时固定(实际上是模板参数)?

所讨论的函数是一个位于性能关键路径中的访问函数,因此我正在寻找尽可能少的开销。

首先想到的是 std::initializer_list,尽管有人告诉我它很便宜,但它仍然是一个不需要创建和复制的对象。更重要的是,它有一种时髦的方式来访问它的元素 initializer_list::begin[i] (这是另一个我不关心的对象)并且不会将参数的数量严格限制为 N ,但这是一个小问题。

其次是模板参数包。那些可以成为可行的候选人吗?我将不得不使用递归来访问 N 个值。

我试图在此伪代码中展示的目标:

template<int dim, class T> class linear_searchspace {

    template<T...args> operator() (args) {
        return std::tie(some_kinda_structure[args[0]], some_kinda_structure[args[1]], some_kinda_structure[args[3]]);
    }

};

我怎么能把它变成实际可行的递归形式呢?

澄清 args 应该是坐标。每个坐标是一个值在维度中的索引。因此传递了 N 个坐标,将返回 N 个值。这就像同时访问 N 个 vector 。我想为每个参数添加一个偏移量,这取决于参数的索引,因为它存储了一个数组,其中偏移量的索引对应于参数的索引。计算将是简单的算术。

什么是合适的返回类型?这将访问的结构很可能包含数值,最多是元组。 std::tuple 是我能做的最好的,还是有可能制作出性能更高的东西?

关于参数,任何东西都可以,甚至是宏。我很高兴听到这些年来你想出了什么把戏。

最佳答案

template <std::size_t DIM, typename T>
class linear_searchspace
{
public:
    template <typename... Args>
    inline constexpr auto operator()(Args... args) const
        noexcept(noexcept(T{std::declval<T>()}))
        -> std::tuple<decltype((void)args, T{std::declval<T>()})...>
    {
        static_assert(sizeof...(Args) == DIM, "wrong number of indices!");
        using Tuple = std::tuple<decltype((void)args, T{std::declval<T>()})...>;
        return get<Tuple>(make_index_sequence<sizeof...(Args)>{}, args...);
    }

private:
    template <typename Tuple, typename... Args, std::size_t... Is>
    inline constexpr Tuple get(index_sequence<Is...>, Args... args) const
        noexcept(noexcept(T{std::declval<T>()}))
    {
        return Tuple((some_kinda_structure[args] + Is)...);
        //                                       ^^^^
        // some calculation for each element based on index (here simple addition)
    }

    T some_kinda_structure[DIM]; // implementation defined
};

(index_sequence的实现在demo中)

DEMO

通过上述解决方案,可以通过 constexpr 对象获得最高性能,因为整个操作是在编译时评估的:

int main()
{
    constexpr linear_searchspace<5, int> lsp{};

    // evaluated at compile-time
    constexpr auto t = lsp(0, 1, 2, 3, 4);
    static_assert(std::get<1>(t) == 1, "!");

    // evaluated at run-time
    auto t2 = lsp(4, 3, 2, 1, 0);
    assert(std::get<3>(t2) == 3);
}

关于c++ - 采用 N 个参数并返回 N 个值的高性能解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26451409/

相关文章:

C++ - 在模板类之外但在头文件中定义成员函数

c++ - 奇怪的结果 (`\210` ) 打印字符数组的末尾时

c++ - C 运行时库版本兼容性 : updates require rebuilds?

python - .isin() 比 .query() 快吗

python - Django 的性能问题

performance - Open XML SDK v2.0 删除 20,000 多行 Excel 文件中的第一行时出现性能问题

c++ - 从另一个类创建特定于另一个类的类的优雅/有效方法

c++ - 使用什么列表类?

c++ - 从 ‘const int*’ 到 ‘int*’ 的无效转换

c++ - 模板函数和 Const/NonConst 引用参数