(C++) 有什么方法可以优化这个循环吗?不能将函数指针用作类内部
(c++) any way to optimize this loop? can't use function pointer as its inside a class
尝试优化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);
}
}
}
};
以下是如何使用指向成员函数的指针:
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慢,除非编译器进行了优化。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么虚函数不能是静态的和全局的?
- 是否可以将函数导入命名空间,但不能导出它?
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 为什么我不能将引用作为 std::async 的函数参数传递
- 不能调用构造函数
- 为什么我不能引用指向实例化对象的函数的指针?
- 不能对类型化模板使用 STL 函数
- 为什么函数名不能与返回名类型相同?
- 不能制作需要布尔成员函数的C++20概念
- 为什么我不能直接从返回指针的函数返回对指针的引用?
- 为什么继承的受保护构造函数不能公开?
- 为什么我不能创建一个 TSubclassOf<> 在 SpawnActor() 函数中使用?
- Clang-Format 不能正确分配函数参数