我应该从包装功能期望多少开销
这个问题或多或少类似于此Extend an existing API: Use default argument or wrapper function? 但有很大不同。
请阅读。我应该从包装功能期望多少开销
我有一个Foo类,它具有在我的程序的许多部分中使用的函数oldFunc。
为了向Foo引入新行为,我实现了newFunc,并将其设置为private,以使oldFunc的调用者继续使用相同的API,但如果他们通过调用setUseType()函数设置标志 可以获得新行为。
伪代码如下:
class Foo
{
public:
Foo(){ useNew = false;}
void setUseType(bool useType){ useNew = useType;}
std::string oldFunc(int r)
{
if(useNew)
{
return newFunc(r);
}
return std::string("Some value after doing some work");
}
private:
std::string newFunc(int r){ return std::string("Some value after doing some work");}
bool useNew;
};
问题oldFunc
多次调用(百万次)循环中。
我应该期望从oldFunc
内包装newFunc
多少开销。 理论上,如果oldFunc
和newFunc
其中在实现中有一个理由是有理由期望 呼叫与标志设置UseType(true)
要慢?
在这种特殊情况下,任何非白痴编译器都不会有任何开销,因为函数将被内联。您的代码将相当于:
class Foo
{
public:
Foo(){ useNew = false;}
void setUseType(bool useType){ useNew = useType;}
std::string oldFunc(int r)
{
if(useNew)
{
return std::string("Some value after doing some work");//newFunc inlined here
}
return std::string("Some value after doing some work");
}
private:
bool useNew;
};
如果没有内联,就呼叫到新功能的额外跳。这就是所有额外的计算时间进入的地方。即使考虑数百万次呼叫,这种额外的跳跃很可能会导致延迟少得多。如果您确实遇到了速度问题并找出真正的瓶颈,我建议您进行一些分析 - 很可能不是额外的呼叫。
你可以测量它。那么你肯定会知道。 (至少为了比较目的)。
我认为任何现代编译器都会优化代码,以便通过oldFunc()调用newFunc()并不比直接调用oldFunc()更昂贵。
但是请注意,您添加了一条if语句,每次调用oldFunc()时都会对其进行评估,无论您是使用旧功能还是新功能。所以现在你已经对oldFunc()的所有调用慢了一点。
添加if语句的开销可能在噪声中或可能很重要,这取决于。您应该测量调用原始的oldFunc()1,000,000次需要多长时间,然后使用添加的if语句来衡量相同的事情。如果差异显着,您可能需要考虑允许客户端选择使用哪种方法来避免if语句的其他方法,例如通过成员函数指针。
这似乎是一种脆弱的方式来实现版本...? –
'useNew'在运行时更改吗?如果没有,你可以将它编译为一个常量,并完全摆脱开销。 –
@Kerrek SB'useNew'是一个运行时参数 – user841550