我是否应该担心载体中含有太多水平的载体? 例如,我有一个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
第二种方法更好,但我想更慢。
如果我担心与此相关的性能问题,请给我任何建议, 或者......
由于
答案 0 :(得分:2)
效率不会真正影响你的代码(矢量随机访问的成本基本上没什么),你应该关注的是滥用矢量数据结构。
你应该在类上使用向量来处理像这样复杂的事情。具有正确定义的接口的类不会使您的代码更有效,但它将来会使维护变得更加容易。
您当前的解决方案也可能遇到未定义的行为。以您发布的代码为例:
Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
如果pos.a
,pos.b
,pos.c
,pos.d
引用的向量索引在其中一个向量中不存在,会发生什么?您将进入未定义的行为,您的应用程序可能会出现段错(如果您很幸运)。
要解决此问题,您需要在尝试检索Block
对象之前比较所有向量的大小。
e.g。
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
类中使用向量,但是如果它位于方法内,您可以在以后删除向量滥用,而无需在其他位置更改任何代码(见:Law Of Demeter)!
答案 1 :(得分:1)
改为使用引用。这不会复制对象,只是创建别名以使其更有用,因此不会触及性能。
Block& b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
(观看&符号)。使用b时,您将使用原始矢量。
但正如@delnan所说,你应该更担心你的代码结构 - 我相信你可以用更合适和更可维护的方式重写它。
答案 2 :(得分:-1)
您应该担心具体的答案,因为我们不知道您的计划的约束条件甚至是什么?
鉴于我们所知道的很少,你提供的代码并不是那么糟糕。
您展示的第一种和第二种方法在功能上是相同的。默认情况下,两者都将返回一个对象引用,但根据赋值可能会导致复制。第二个肯定会。
Sasha是对的,你可能想要一个参考而不是一个对象的副本。根据您使用它的方式,您可能希望将其设为常量。
由于你正在使用向量,每次调用都是固定时间,应该非常快。如果您真的担心,请拨打电话并考虑每秒拨打电话的频率。
您还应该考虑数据集的大小,并考虑其他数据结构(可能是数据库)是否更合适。