(C++) 有什么方法可以优化这个循环吗?不能将函数指针用作类内部

(c++) any way to optimize this loop? can't use function pointer as its inside a class

本文关键字:不能 函数 指针 内部 循环 什么 C++ 方法 优化      更新时间:2023-10-16

尝试优化fun_a1()函数。变量jfun_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);
            }           
        }       
    }   
};

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

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

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

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

然而,如果你想明确这一点,答案不是函数或方法指针。它是lambda和函子。

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快的原因。

"optimize"是模糊的,除非,否则永远不应该询问

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

  • 2,需要进行特定的优化。

你所要求的是优化这个"切换"语句

是的,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慢,除非编译器进行了优化。