是否值得在各处使用策略而不是条件(将运行时检查编译时间)?

时间:2016-01-26 12:51:56

标签: c++ templates metaprogramming conditional-statements

让我们想象一下程序中有一个条件:

void foo(bool condition)
{
    .... a lot of work....

    if (condition)
        something1;
    else
        something2;

    .... a lot of work....
}

如果在编译时,在foo()的每次调用中我们知道我们需要something1或something2,我们可以将程序改为这个:

template <bool condition>
void foo()
{
    .... a lot of work....

    SomePolicy<condition>::do_something();

    .... a lot of work....
}

template <bool Condition>
class SomePolicy
{
public:
    static void do_something()
    {
        something1;
    }
};

template <>
class SomePolicy<false>
{
public:
    static void do_something()
    {
        something2;
    }
};

因此,在编译时通过调用foo<true>foo<false>.进行运行时检查是否值得在任何地方进行并摆脱某些条件(可能会提高管道性能)?除了一些丑陋的代码之外,还有什么不利之处吗?

P.S。问题是我们不想复制所有foo代码并在不同的地方调用foo1和foo2。

3 个答案:

答案 0 :(得分:1)

我认为在编译器优化了你的语句之后,它最终会得到大致相同的代码。您必须衡量性能以获得编译器的确切答案。

答案 1 :(得分:1)

  

除了一些丑陋的代码之外,还有什么不利之处吗?

您的代码对可获得的内容的可读性稍差?您已将条件检查从运行时移动到编译时,但是您是否首先分析了代码并确定这些检查是否在热门路径上?

  • 您是否需要编写其他测试来解释您的重构?

  • 按照你重构的方式,你已经从需要的地方移开了一些逻辑,并且可能允许其他人(错误地)使用它。

  • 模板化通常会增加编译时间。如果你有成千上万的这些检查,它可能是非常重要的。

所以问题是,它值得吗?大概。一般来说,从运行时到编译时的移动计算=快乐的最终用户。但如果它存在额外错误的风险以及更大,更不易读的代码库以获得可忽略的性能增益,那么您可能需要三思而后行。

答案 2 :(得分:1)

  

这值得在各处做,并摆脱一些条件(可能会提高管道性能)?

不,因为管道停滞不是无处不在的瓶颈可能值得在一个热点中进行,你已经测量了由指令之间的长依赖链引起的瓶颈。 “大量工作”中间的一个分支很少对绩效产生重大影响。

  

除了一些丑陋的代码之外,还有什么不利之处吗?

它限制了在编译时检查的条件,而不是在运行时。在运行时具有可变输入的程序通常更通用。

正如您在评论中指出的那样,您确实可以使用所描述的策略将多个运行时检查减少为一个。但是生成所有(显然很大,因为他们做了很多工作)功能两次,无处不在会导致可执行文件大小显着增长,这是一种不良的副作用。

此外,它会强制您使用模板,这会强制实现在标头中。如果您在整个代码中执行此操作,那么大多数代码将在头文件中实现,并且在修改实现时将导致大量重新编译。这是大项目中的问题。