1

试图优化fun_a1()功能。变量j在范围内不变fun_a1()。因此,为每个“i”迭代检查 j==1 或 2 或 3 显然是对 CPU 周期的浪费。但是如果我试图将条件评估带到循环之外,我必须为每个条件编写冗余循环。在 C 语言中,我可以通过使用函数指针轻松解决这个问题。但是,C++ 不允许指向非静态函数的指针。我发现了一些描述神秘的“指向成员”的链接。(示例 1示例 2)但是仍然不清楚如何从对象本身内部使用它,例如从 fun_a() 内部?还是可以通过其他方式进行优化?

class A{
    void fun_b(int i);

    void fun_c(int i);

    void fun_d(int i);

    void fun_f(int i);

    void fun_a1(int j){

        for(int i=0; i<1000; i++){

                 if(j==1) fun_b(i);
            else if(j==2) fun_c(i);
            else if(j==3) fun_d(i);

            fun_f(i);           
        }

    }


    void fun_a2(int j){

        if(j==1){           
            for(int i=0; i<1000; i++) { 
                fun_b(i); 
                fun_f(i); 
            }
        }
        else if(j==2){          
            for(int i=0; i<1000; i++) { 
                fun_c(i);
                fun_f(i);
            }            
        }
        else if(j==3){
            for(int i=0; i<1000; i++) { 
                fun_d(i);           
                fun_f(i);
            }           
        }       
    }   
};
4

3 回答 3

6

以下是如何使用指向成员函数的指针:

void (A::*fun)(int);
if(j == 1) fun = &A::fun_b;
else if(j == 2) fun = &A::fun_c;
else if(j == 3) fun = &A::fun_d;

for(int i=0; i<1000; i++) {
    (this->*fun)(i);
    fun_f(i);
}
于 2013-02-10T04:32:08.653 回答
1

使用函数指针,如果编译器不删除它们,会严重影响性能。

未更改的局部变量上的原始 if 可能会在循环外进行优化:这不是一个非常花哨的优化。

但是,如果你想明确这一点,答案不是函数或方法指针。它是 lambdas 和仿函数。

template<typename Functor>
void fun_a2_internal(Functor f) {
  for(int i = 0; i < 1000; ++i) {
    f(i);
  }
}

void fun_a2(int j) {
  if (j==1)
    fun_a2_internal([&](int i){ fun_b(i); fun_f(i); });
  else if (j==2)
    fun_a2_internal([&](int i){ fun_c(i); fun_f(i); });
  else if (j==3)
    fun_a2_internal([&](int i){ fun_d(i); fun_f(i); });
}

这里我们写一个fun_a2_internal它的工作是做一个循环,并在循环中做一些任务。

我们fun_a2通过 lambda 将该任务作为函子传递。

这具有编译器在编译循环时了解循环体的细节的效果,因为函子operator()是非虚拟的,因此对于每个实例都是相同的。

一般来说,如果您对优化问题的回答是“使用函数指针”(或成员指针),那么您的回答就错了。

这种技术是 C++std::sort比 C 更快的原因qsort

于 2013-02-10T06:22:29.490 回答
-2

“优化”含糊不清,除非

  • 1,有一个特定的问题被问到,说教授基于效率的概念

  • 2、有一个特定的优化要做。

你要问的是优化这个“switch”语句

是的,switch 语句在这种情况下更干净,但更有效的方法是创建一个函数指针数组,指向包含这些循环的 void 函数,然后执行

doFunction[j]();

例如

typedef void (*myfunc)(void);

myfunc options[10];

main()
{
    options[0] = (void*)loop1;
    options[1] = (void*)loop2;
    options[2] = (void*)loop3;
    options[3] = (void*)loop4;  
}

PS:除非经过编译器优化,否则 i++ 比 ++i 慢。

于 2013-02-10T04:32:25.800 回答