来自Scott Meyers的Effective C ++:
template<typename T, std::size_t n>
class SquareMatrix: private SquareMatrixBase<T> {
public:
SquareMatrix( )
: SquareMatrixBase<T>(n, 0),
pData(new T[n*n])
{
this->setDataPtr(pData.get());
}
...
private:
boost::scoped_array<T> pData;
};
无论数据在何处 存储,臃肿的关键结果 观点是,现在很多 - 也许 所有 - SquareMatrix的成员 函数可以是简单的内联调用 到共享的基类版本 与所有其他矩阵持有 相同类型的数据,无论他们是谁 尺寸。与此同时,SquareMatrix 不同大小的物体是 不同的类型,所以尽管如此, SquareMatrix&lt; double,5&gt;和 SquareMatrix&lt; double,10&gt;对象使用 同一个成员的职能 SquareMatrixBase&lt; double&gt;,没有 通过的机会 SquareMatrix&lt; double,5&gt;反对a 功能期待a SquareMatrix&lt; double,10&gt;。很好,不是吗?
很好,是的,但不是免费的。版本 用矩阵大小反转 硬连线进入他们很可能 生成比共享更好的代码 大小作为传递的版本 函数参数或存储在 宾语。例如,在 尺寸特定版本,尺寸 因此,它将是编译时常量 有资格获得此类优化 不断传播,包括他们的 被折叠成生成的 指令作为即时操作数。 这不可能在 尺寸无关的版本。
在上一段的上述描述中,它被提及为“因此有资格作为不断传播的优化,包括将它们折叠成 生成的指令作为立即操作数“。这个声明是什么意思?请请解释这个。
谢谢!
答案 0 :(得分:8)
Constant Propagation是一个非常简单的(在原理上)优化留给编译器。
size_t radius = 5;
size_t diameter = 2*radius;
float perimeter = diameter * 3.1416f;
编译器会通过传播常量来减少这一点:
radius
的值已知2*radius
的计算(这是常数折叠)diameter
的值diameter * 3.1416f
perimeter
的值该计划因此相当于:
size_t radius = 5;
size_t diameter = 10;
float perimeter = 31.416f;
请注意,还有许多其他形式的优化,例如,如果现在不再需要radius
和diameter
,我们可以删除它们并仅保留perimeter
。
答案 1 :(得分:0)
如果你有原始代码,如:
a:=3;
b:=4;
b+=1;
b+=2;
a:=a+b;
然后编译器可以将语句优化为:
b==7;
a==10;
这称为恒定传播和恒定折叠。