优化指针或标量的函数

时间:2018-04-16 13:08:38

标签: c++ templates

我有一个复杂的程序,我正在尝试优化。经过一些测试后,我分离了一个如下所示的函数:

void sum(int* res, int* a, int* b, int size){
    for (int i=0;i<size;i++){
       res[i] = a[i] * (b[i]+1);
    }
}

我经常使用重复的第二个或第三个参数调用此函数,因此我将其优化如下

void sum(int* res, int* a, int b, int size){
    for (int i=0;i<size;i++){
       res[i] = a[i] * (b+1);
    }
}

或如下

void sum(int* res, int a, int* b, int size){
    for (int i=0;i<size;i++){
       res[i] = a * (b[i]+1);
    }
}

请注意,第二个或第三个参数是标量或指针。有没有办法使用C ++模板魔术来拥有所有三个版本而不必重复实现?

免责声明:我的功能太复杂,无法在此列出,并不像示例那么简单。但如果我知道如何为这个简单的例子编写模板,我应该能够使解决方案适应我的问题。

2 个答案:

答案 0 :(得分:4)

这里的想法只是让sum成为一个模板并分解实现之间的差异,即数组或标量访问:

namespace detail_arrayish {
    template <class T>
    auto &access(T &single, int) {
        return single;
    }

    template <class T>
    auto &access(T *array, int n) {
        return array[n];
    }
}

template <class A, class B>
void sum(int* res, A a, B b, int size) {
    using detail_arrayish::access;

    for (int i=0;i<size;i++){
       res[i] = access(a, i) * (access(b, i) + 1);
    }
}

这应该由任何自尊的编译器完全优化。

See it live on Coliru

答案 1 :(得分:0)

假设您的功能很复杂,但您的条款相对简单,您不一定需要模板,重载正确的保理就足够了。

E.G。

void sum(int* res, int a, int b, int i){
    // your complex function here
    res[i] = a * (b+1);
}


void sum(int* res, int* a, int* b, int size){
    for (int i=0; i<size; ++i){
       sum(res, a[i], b[i], i)
    }
}

void sum(int* res, int* a, int b, int size){
    for (int i=0; i<size; ++i){
       sum(res, a[i], b, i)
    }
}

void sum(int* res, int a, int* b, int size){
    for (int i=0; i<size; ++i){
       sum(res, a, b[i], i)
    }
}

工作可以在一个函数中完成,而重载只在需要时同步处理索引。

在优化方面,如果没有看到这个功能,很难说明会发生什么。

Re:&#34;优化速度&#34;,假设您知道您的算法已经处于良好状态并且正在充分利用适当的Cpu指令,如果您在没有常量和无别名承诺的情况下大量使用指针你更有可能为你的功能布局以及它们的调用方式付出代价(当它以这种直接的方式进行间接时,无论是模板化还是过载,编译器通常都会做得不错。)

如果你的类型是文字/简单,不要错误地假设尽可能多的指针,因为指针或参考将有所帮助,它通常会赢(并且有时会有害)。从长远来看,以简单术语为价值的核心功能可能会获胜。

这可能适用于您的工作,也可能不适用于您的工作,很难从简单示例中推断出来。

P.S。 我还将这些i++替换为++i,因为他们一直困扰着我:)