让我们想象一下程序中有一个条件:
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。
答案 0 :(得分:1)
我认为在编译器优化了你的语句之后,它最终会得到大致相同的代码。您必须衡量性能以获得编译器的确切答案。
答案 1 :(得分:1)
除了一些丑陋的代码之外,还有什么不利之处吗?
您的代码对可获得的内容的可读性稍差?您已将条件检查从运行时移动到编译时,但是您是否首先分析了代码并确定这些检查是否在热门路径上?
您是否需要编写其他测试来解释您的重构?
按照你重构的方式,你已经从需要的地方移开了一些逻辑,并且可能允许其他人(错误地)使用它。
模板化通常会增加编译时间。如果你有成千上万的这些检查,它可能是非常重要的。
所以问题是,它值得吗?大概。一般来说,从运行时到编译时的移动计算=快乐的最终用户。但如果它存在额外错误的风险以及更大,更不易读的代码库以获得可忽略的性能增益,那么您可能需要三思而后行。
答案 2 :(得分:1)
这值得在各处做,并摆脱一些条件(可能会提高管道性能)?
不,因为管道停滞不是无处不在的瓶颈。 可能值得在一个热点中进行,你已经测量了由指令之间的长依赖链引起的瓶颈。 “大量工作”中间的一个分支很少对绩效产生重大影响。
除了一些丑陋的代码之外,还有什么不利之处吗?
它限制了在编译时检查的条件,而不是在运行时。在运行时具有可变输入的程序通常更通用。
正如您在评论中指出的那样,您确实可以使用所描述的策略将多个运行时检查减少为一个。但是生成所有(显然很大,因为他们做了很多工作)功能两次,无处不在会导致可执行文件大小显着增长,这是一种不良的副作用。
此外,它会强制您使用模板,这会强制实现在标头中。如果您在整个代码中执行此操作,那么大多数代码将在头文件中实现,并且在修改实现时将导致大量重新编译。这是大项目中的问题。