【发布时间】:2022-01-22 01:11:19
【问题描述】:
我听说向量的向量在性能方面很糟糕。比如我有下面的二维std::vector:
std::vector< std::vector<char> > characterMatrix;
// for iterating
for ( int row = 0; row < getY_AxisLen( ); ++row )
{
for ( int column = 0; column < getX_AxisLen( ); ++column )
{
std::cout << characterMatrix[ row ][ column ];
}
}
在这种方法中,矩阵会在 3-12 毫秒内打印在我的系统上。如果我看到例如减少,我会很高兴。 1-3 毫秒。
据我所知,每个内部向量(即 rows)都存储在堆内存的不同位置。所以这会导致很多碎片。
不仅如此,我的编译器中的 sizeof(std::vector) 返回 24(字节)。所以这意味着,例如,如果characterMatrix 有 50 行(也称为内部向量),那么它将在堆上分配 24*50 == 1200 字节来存储这 50 个向量的控制块这是在矩阵中实际数据 (chars) 占用的空间之外的。
现在,如果我想将所有 chars 保存在一个连续的内存块中,也许我可以将其写为一维向量,例如:
std::vector< char > characterMatrix;
// for iterating
for ( int row = 0; row < getY_AxisLen( ); ++row )
{
for ( int column = 0; column < getX_AxisLen( ); ++column )
{
std::cout << characterMatrix[ row * getX_AxisLen( ) + column ]; // is this correct?
}
}
这是一种有效的方法吗?如果我想以这种方式更改矩阵变量的实现,有人能告诉我应该记住什么吗?可能的缺点是什么?
【问题讨论】:
-
我“听说”在做出决定之前应该测量、分析和基准测试(优化的构建)。
-
nitpick:内部向量作为外部元素连续存储,但您的推理是正确的,因为内部向量将元素存储在堆上,因此矩阵的元素不连续
-
性能取决于很多因素,并且应该始终进行衡量!优化通常以可读性/可维护性为代价,因此就像工程一样,它是一种权衡。但是是的,向量的向量可能会导致数据在内存中更加分散,然后是连续分配,因此您不会充分利用缓存(预测)。也许你听说过 if 也很糟糕(分支预测)......那么你的实际问题是什么?
-
视情况而定。例如,如果您经常调整行大小,那么
std::vector<std::vector<char>>甚至可能比std::vector<char>执行得更好。对于稀疏矩阵,您可以考虑使用std::map<index,int>。正如其他人所说,唯一知道的方法就是测量 -
@digito_evo:只是我在其他问题上看到的大多数 cmets 都类似于 “将一维向量用于矩阵”,即使对于初学者来说也没有其他考虑 :-(。在这里你得到了“先测量”,“它是瓶颈吗?”,“它更具可读性”?这让我很开心。跨度>
标签: c++ multidimensional-array dynamic-memory-allocation stdvector