第二组功能仅在一行代码中有所不同

jav*_*ver 4 c++ maintainability performance function code-duplication

我有两个性能关键的功能,如下所示:

insertExpensive(Holder* holder, Element* element, int index){
    //............ do some complex thing 1 
    holder->ensureRange(index);//a little expensive
    //............ do some complex thing 2
}
insertCheap(Holder* holder, Element* element, int index){
    //............ do some complex thing 1
    //............ do some complex thing 2
}
Run Code Online (Sandbox Code Playgroud)

如何将2个功能组合在一起以提高可维护性?

我糟糕的解决方案

解决方案1.

insertExpensive(Holder* holder, Element* element, int index){
    do1();
    holder->ensureRange(index);//a little expensive
    do2();
}
insertCheap(Holder* holder, Element* element, int index){
    do1();
    do2();
}
Run Code Online (Sandbox Code Playgroud)

这将是丑陋的.如果do2想要一些局部变量,这也是不切实际的do1.

解决方案2.

insert(Holder* holder, Element* element, int index, bool check){
    //............ do some complex thing 1 
    if(check)holder->ensureRange(index);//a little expensive
    //............ do some complex thing 2
}
Run Code Online (Sandbox Code Playgroud)

它需要对每次通话进行有条件的检查.

解决方案3. (草案)

template<bool check> insert(Holder* holder, Element* element, int index){
    //............ do some complex thing 1       (Edit2 from do1());
    bar<check>();
    //............ do some complex thing 2       (Edit2 from do2());
}
template <>
inline void base_template<true>::bar() {  holder->ensureRange(index); }
template <>
inline void base_template<false>::bar() {  }
Run Code Online (Sandbox Code Playgroud)

过度杀伤和不必要的复杂性?

编辑1:方法 的优先级标准优先顺序如下: -
1.最佳性能
2.减少代码重复
3.减少总代码行
4.专家和初学者更易于阅读

编辑2:编辑第3个解决方案.感谢mvidelgauz和Wolf.

JVA*_*pen 6

你的解决方案2实际上还不是那么糟糕.如果此代码在标头内,则将其隐式地视为内联代码.(我已经明确地写过)如果用true或false调用它,编译器可以删除if语句,尽管它取决于一系列因素来知道它是否会这样做.(内联后的整体尺寸,常数的可见性,调整......)

inline void insert(Holder* holder,Element* element,int index, bool check){
    do1();
    if (check)
        holder->ensureRange(index);//a little expensive
    do2();
}
Run Code Online (Sandbox Code Playgroud)

解决方案3实际上是您想要实现的,因为模板需要为每个不同的调用实现新的函数实例化,因此它将删除死代码.但是它的编写方式与编写解决方案2的方式非常相似.

template <bool check>
inline void insert(Holder* holder,Element* element,int index){
    do1();
    if (check)
        holder->ensureRange(index);//a little expensive
    do2();
}
Run Code Online (Sandbox Code Playgroud)

如果您有C++ 17,则不再需要依赖编译器来删除死代码,因为您可以强制它通过constexpr-if跳过某些代码.这种结构将保证删除if语句中的代码,因为它甚至不需要编译.

template <bool check>
inline void insert(Holder* holder,Element* element,int index){
    do1();
    if constexpr (check)
        holder->ensureRange(index);//a little expensive
    do2();
}
Run Code Online (Sandbox Code Playgroud)