我应该担心向量中有太多级别的向量吗
Should I be worried about having too many levels of vectors in vectors?
我应该担心向量中的向量级别太多吗?例如,我有一个5级的层次结构,我有这样的代码我的整个项目:
rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]
其中每个元素是向量。整件事是一个向量的向量。。。使用这个仍然应该比复制这样的对象快得多:
Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
// use b
第二种方法要好得多,但我想速度较慢。
如果我应该担心与此相关的性能问题,请给我任何建议,否则。。。
感谢
代码中的效率不会真正受到影响(向量随机访问的成本基本上是零),您应该关注的是向量数据结构的滥用。
对于像这样复杂的东西,你几乎没有理由在类上使用向量。具有正确定义接口的类不会提高代码的效率,但它会使将来的维护更加容易。
您当前的解决方案也可能遇到未定义的行为。以你发布的代码为例:
Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
现在,如果pos.a
、pos.b
、pos.c
、pos.d
所指的向量索引不存在于其中一个向量中,会发生什么?您将进入未定义的行为,您的应用程序可能会出错(如果幸运的话)。
要解决此问题,在尝试检索Block
对象之前,需要比较所有向量的大小。
例如
Block b;
if ((pos.a < rawSheets.size()) &&
(pos.b < rawSheets[pos.a].countries.size()) &&
(pos.c < rawSheets[pos.a].countries[pos.b].cities.size()) &&
(pos.d < rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks.size()))
{
b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
}
你真的会在每次需要盖帽时都这么做吗?!!
你可以这样做,或者你至少可以把它封装在一个类中。。。
示例:
class RawSheet
{
Block & FindBlock(const Pos &pos);
std::vector<Country> m_countries;
};
Block & RawSheet::FindBlock(const Pos &pos)
{
if ((pos.b < m_countries.size()) &&
(pos.c < m_countries[pos.b].cities.size()) &&
(pos.d < m_countries[pos.b].cities[pos.c].blocks.size()))
{
return m_countries[pos.b].cities[pos.c].blocks[pos.d];
}
else
{
throw <some exception type here>;
}
}
然后你可以这样使用它:
try
{
Block &b = rawSheets[pos.a].FindBlock(pos);
// Do stuff with b.
}
catch (const <some exception type here>& ex)
{
std::cout << "Unable to find block in sheet " << pos.a << std::endl;
}
至少,您可以继续在RawSheet
类中使用向量,但由于它在方法中,您可以在以后删除向量滥用,而不必在其他地方更改任何代码(请参阅:Demeter定律)!
请改用引用。这不会复制对象,只是创建一个别名以使其更可用,因此性能不会受到影响。
Block& b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
(注意电流)。使用b时,将使用原始向量。
但正如@delnan所指出的,你应该更加担心你的代码结构——我相信你可以用一种更合适、更可维护的方式重写它。
您应该担心具体的答案,因为我们不知道程序的约束是什么,甚至不知道它的作用是什么?
考虑到我们所知甚少,你给出的代码并没有那么糟糕。
您展示的第一种和第二种方法在功能上是相同的。默认情况下,两者都将返回对象引用,但根据指定情况,可能会生成副本。第二个肯定会。
Sasha是对的,你可能想要一个引用而不是对象的副本。根据您使用它的方式,您可能希望将其设为常量。
由于您使用的是向量,所以每次调用都是固定的时间,并且应该非常快。如果你真的很担心,给电话计时,并考虑一下每秒打电话的频率。
您还应该考虑数据集的大小,并考虑其他数据结构(也许是数据库)是否更合适。
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 计算排序向量的向量中唯一值的计数
- 矩阵向量乘法(cublasDgemv)返回零
- 一对向量构造函数:初始值设定项列表与显式构造
- 将结构向量排序为子组
- 在C++中调整向量中的索引
- 我应该担心向量中有太多级别的向量吗