假设例如,我有两个函数几乎是完全一样的,这代表了系统的瓶颈,那是这个样子,(要复杂得多):保持代码DRY不牺牲效率
void f1(int s)
{
for(size_t i = 0, END = m_v.size(); i < END; ++i)
{
int bin_id = binId(m_v[ i ], s);
m_result[ bin_id ] += m_w[ i ]; //
}
}
void f2(int s)
{
for(size_t i = 0, END = m_v.size(); i < END; ++i)
{
int bin_id = binId(m_v[ i ], s);
m_result[ bin_id ] += 1.f; //
}
}
除了您在代码的一行中使用变量或常量之外,所有内容都是相同的。如前所述,假设实际的代码要复杂得多。最好不要将它复制两次,但要有一点不同,因为它需要确保每个区域保持一致。我可以这样做,将它们合并为一个:
void f3(bool use_weight, int s)
{
if(use_weight)
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
result[ bin_id ] += m_w[ i ]; //
}
}
else
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
result[ bin_id ] += 1.f; //
}
}
}
但是,这仍然是重复的代码,只是在一个单一的功能。我们能做到这一点,但它会给性能越差:
void f3(bool use_weight, int s)
{
for(size_t i = 0, END = v.size(); i < END; ++i)
{
int bin_id = binId(v[ i ], s);
if(use_weight)
{
result[ bin_id ] += m_w[ i ]; //
}
else
{
result[ bin_id += 1.f; //
}
}
}
,并且调用代码如下所示:
bool use_weight = something.use_weight();
const int N = very_large_number;
for(int s = 0; s < N; ++s)
{
f3(use_weight, s);
}
同样,假定代码要复杂得多,使得F3,例如是实际上重复了很多逻辑。
将代码分解成一个'inline'函数,它接受一个参数,并传递一个变量或一个常量应该避免代码重复,并让编译器每次发出适当的代码。 –
你会传递'bool'作为模板参数吗? – qxz
您可以使用lambdas代替两个变体中的代码,并在循环之前将相应的回调设置为变量。但是如果这是一个瓶颈功能,函数调用开销可能会很繁琐。 – Barmar