我正在搜索2D矩阵(或位图)类,它灵活但快速的元素访问。内容灵活的类应允许您在运行时选择维度,并且看起来像这样(简化):
class Matrix
{
public:
Matrix(int w, int h) :
data(new int[x*y]), width(w) {}
void SetElement(int x, int y, int val)
{
data[x+y*width] = val;
}
// ...
private: // symbols
int width;
int* data;
};
使用模板的经常提出的解决方案更快(简化):
template <int W, int H>
class TMatrix {
TMatrix() data(new int[W*H]) {}
void SetElement(int x, int y, int val)
{
data[x+y*W] = val;
}
private:
int* data;
};
这更快,因为代码中的宽度可以“内联”。第一种解决方案不会这样做。但是,这不再灵活,因为您无法在运行时更改大小。
所以我的问题是: 是否有可能告诉编译器生成更快的代码(比如使用模板解决方案时),代码中的大小是否已修复并在运行时依赖时生成灵活的代码?
我试图通过尽可能地写“const”来实现这一点。我用gcc和VS2005尝试过,但没有成功。这种优化对许多其他类似案例都很有用。
答案 0 :(得分:0)
我会选择第一个版本,我自己。
但是,如果你真的想要尝试两全其美,你可以拥有一个Matrix类,它包含一个指向多态实现类型的指针。对于常见大小(例如最多4x4),您可以指向模板实例化,对于更大的大小,您可以指向处理一般MxN情况的实现。
说了这么多,我认为所有的间接&amp;虚拟调用将否定可能来自模板的任何性能改进。我认为你不能吃蛋糕和蛋糕。在这种情况下也要吃它。
如果您总是处理编译时已知大小的数据(例如图形/几何向量),那么您最好使用模板版本(可能以静态大小(非堆分配)存储数据)阵列)。如果您需要任意数据的一般功能,请改用动态版本。
答案 1 :(得分:0)
当然,您的需求可能会有所不同,但我会跳过自动生成,只需使用一组简单的“固定”版本即可。例如。 Vector3,Vector4,Matrix3x3,Matrix3x4和Matrix4x4。我想你可以从模板化版本中获得所有这些,但它不会产生任何特定的性能差异。
您是否有任何特殊原因希望能够在运行时更改尺寸?因为我建议只要在需要进行更改的情况下(从我怀疑是罕见的)实例,只需从一个复制到另一个就不会非常昂贵。
最后 - 我见过的事情是命名元素访问以及数组,但是你只能使用“硬编码”类型。类似的东西:
class Vector3
{
public:
// other stuff...
union
{
struct { float x, y, z; };
float m[3];
};
};
(这可能不是完全合法的C ++,适合您的编译器。)
哦,即使是模板化版本也不需要使用新版本。只需将数据声明为float data[W*H];
将其从堆中取出将比“优化”一些数学运算带来更大的性能提升。
答案 2 :(得分:0)
与完整的答案不同,但有些信息可能会有所帮助(如果您还没有意识到这些):OpenCV和Boost (uBLAS)都非常好(快速/完整/全功能)矩阵实现。我没有查看它们内部以查看它们如何设置/获取元素或在实例化后调整大小。