基于抽象迭代器加速设计的想法

时间:2012-07-04 09:06:43

标签: c++ oop design-patterns

在某些C ++项目中,我正在处理代表各种性质图形的对象。它们都实现了一个通用的抽象接口,我将这个接口简化为一个函数:

class graph {
public:
   ...
   // Create an iterator over the successors of v
   virtual succ_iterator* succ(const vertex* v) const = 0;
   ...
};

succ_iterator类也是一个抽象类,可以迭代v的后继顶点:

class succ_iterator {
public:
   virtual void first() = 0;               // reset the iterator
   virtual void next() = 0;                // move to next successor
   virtual bool done() const = 0;          // no more successor left?
   virtual const vertex* dest() const = 0; // destination vertex
};

因此,图vg的所有后继者的循环如下所示:

succ_iterator* i = g->succ(v);
for (i->first(); !i->done(); i->next()) {
   // use i->dest()
}
delete i;

我经常使用这样的循环来实现图算法。 分析代码表明它花费了大量时间为这些微小的迭代器实例分配内存,所以我想听听有关改进这一点的想法。

不幸的是,我的图形可能有非常不同的实现,因此每个图形可能有自己的succ_iterator接口实现。实质上,graph层次结构中的每个类在succ_iterator层次结构中都有对应的类。例如,可以使用std::vector实现一个图来明确地存储邻接列表(在这种情况下,succ_iteratorstd::vector::const_iterator上方的简单包装器),而另一个图可能是在...上计算的。 fly(在这种情况下,它的succ_iterator实例实际上将计算后续进程中的继承者)。我不知道编译时图形的性质,因此这排除了基于template的实现àla STL。

我考虑过允许每个图表处理succ_iterator池。这似乎需要一个额外的graph::succ_release(succ_iterator*)方法来将迭代器返回到池而不是删除它。我见过的大多数池都是在内存级别完成的:即,当你释放一个对象时,它的析构函数被调用,但是被占用的内存被保留,以便下一个对象将被创建(使用就地构造函数)块。这似乎仍然浪费时间,因为就地构造函数必须设置一个与前一个对象相同的虚拟表指针。我认为在这样的池中,我应该用delete方法替换new + recycle(),该方法与构造函数具有相同的原型。由于代码库非常大,这需要更改界面,我希望在实现之前了解其他设计思路或可能的改进

编辑:我不使用线程。

1 个答案:

答案 0 :(得分:0)

你可以在每个图形实例中缓存succ_iterators并在需要时查找并重用它们吗?

//static or member:
std::map<graph*,succ_iterator*> graph_iterator_cache;

但我不知道你是否有安全问题。