我有一个矢量类,它有加法,乘法,减法,除法等运算符。我正在尝试优化我的程序(它执行了很多向量操作)并且我意识到大约50%的时间花在构造和破坏向量上。我知道这是因为每次我为一个向量调用非复合数学运算符时,都会构造一个新的向量。有没有办法在不使用复合运算符或扩展向量运算的情况下阻止这种情况?
如果我有:
Vector a = Vector(x, y, z);
Vector b = Vector(a, b, c);
Vector c = a + b;
我不能使用+ =因为c是一个全新的向量。我知道我可以加快速度:
c.x = a.x + b.x;
c.y = a.y + b.y;
c.z = a.z + b.z;
但这似乎并不像使用运营商一样干净。
答案 0 :(得分:2)
我明白这是因为 每次我打电话给非化合物 向量的数学运算符,a 新的载体构建。有没有 不使用的方法来防止这种情况 复合运算符或扩展向量 操作
嗯,将两件事物加在一起产生第三件事的本质要求你构建第三件事......那么你在逻辑上可能会问什么呢?
话虽如此,如果您担心使用加法运算符创建的临时值,如果您的编译器支持返回值优化,编译器可能会优化这些临时值。或者,如果你的编译器不支持这个并且你真的想要削减临时值但保留+
运算符,你可能想要研究模拟C ++ 0x移动语义,并为你的向量提供一个rvalue移动构造函数,它将在返回临时值时调用。有关在C ++ 03中实现移动语义的信息,请参阅this article中标题为“移动对象”的部分。一旦C ++ 0x出现,你可以使用&&
运算符替换这些hacks和真正的移动构造函数来进行右值引用。
答案 1 :(得分:1)
确保已启用优化,并且您的编译器正在应用RVO,这是针对这种情况而设计的(但不需要使用)。 (您可能必须在op +实现中使用一种形式的NRVO,例如下面的示例,这有助于编译器识别并应用RVO。)另外,您是否看过blitz++?
Vector operator+(Vector const& a, Vector const& b) {
Vector nrvo;
// or: Vector nrvo (ctor, parameters, here);
//...
return nrvo;
}
还有其他替代方案,例如进行显式复制,然后使用op + =,这适用于RVO不适用的情况:
Vector c; // created somewhere else, and we want to assign to it
// instead of create it "in-place" as RVO does
Vector a, b;
// instead of:
//c = a + b
// use:
c = a;
c += b;
这可以通过expression templates实现,就像blitz ++使用的那样,而不会改变c = a + b
的语法。
答案 2 :(得分:1)
哇那里。你的代码效率很低:
Vector a = Vector(x, y, z);
Vector b = Vector(a, b, c);
这只是效率低下。你想写的是
Vector a(x, y, z);
Vector b(a, b, c);