在C ++中创建大量对象

时间:2010-03-04 16:21:39

标签: c++ iphone performance

是否有任何模式如何处理移动设备上的大量对象实例化(每秒40k)?我需要单独使用这些对象,它们无法组合。重新使用对象可能是一种解决方案。任何提示?

7 个答案:

答案 0 :(得分:7)

是。如果可以的话,将旧对象保留在池中并重新使用它们。 由于内存分配和删除的成本,您将节省大量时间。

答案 1 :(得分:3)

我认为你可以考虑这些设计模式:

  • 对象池

Further info

我希望这对你有所帮助:Object Pooling for Generic C++ classes

答案 2 :(得分:2)

如果对象的大小都相同,请尝试使用带有侵入性自由节点链表的简单单元分配器:

free:
    add node to head of list

allocate:
    if list is non-empty:
        remove the head of the list and return it
    else:
        allocate a large block of memory
        split it into cells of the required size
        add all but one of them to the free list
        return the other one

如果分配和释放都在一个线程中完成,那么您不需要任何同步。如果它们在不同的线程中完成,那么每秒40k上下文切换可能比每秒40k的分配更令人担忧; - )

您可以将单元格设置为“原始内存”(并为您的类使用placement new或overload operator new),或者保持对象始终初始化,即使它们位于“空闲列表”中,并为“新”成员分配所需的任何值。您所做的取决于初始化的成本,以及可能是单元分配器和对象池之间的技术差异。

答案 3 :(得分:2)

如果您的对象是多余的,您可以使用flyweight模式。此模式在类似对象之间共享内存。经典示例是用于字处理程序中字符图形表示的数据结构。

维基百科有summary

提升中有implementation

答案 4 :(得分:1)

很难确切地说如何在没有更多信息的情况下改进代码,但您可能想要查看Boost Pool库。它们都为不同的特定用例提供了快速分配内存的不同方法。选择最适合您用例的那个。

答案 5 :(得分:0)

如果对象大小相同,您可以分配大块内存并使用placement new,这将有助于分配成本,因为它将全部位于连续内存中:

Object *pool = malloc( sizeof(Object) * numberOfObjects );
for(int i=0; i<numberOfObjects; i++)
    new (&pool[i]) Object()  

答案 6 :(得分:0)

我使用类似的模式来编程随机反应扩散系统(台式计算机上每秒数百万个对象创建)和实时图像处理(再次,每秒数十万或数百万)。

基本思路如下:

  • 创建一个分配器,分配所需对象的大型数组;要求此对象具有“下一个”指针(我通常创建一个用下一个指针包装对象的模板)。
  • 每当你需要一个对象时,从这个分配器中获取一个(使用从你调用的内存块初始化的新语法)。
  • 每次完成后,将其交还给分配器并将其放在堆栈上。
  • 如果堆栈非空,分配器会从堆栈中提供一些东西,否则会从其数组缓冲区中获得某些东西。如果用完缓冲区,可以分配另一个更大的缓冲区并复制现有的已用节点,或者让分配器维护一堆完全使用的分配块。
  • 完成所有对象后,删除分配器。附带好处:您不需要确保释放每个单独的对象;他们都会消失。边成本:你最好确保在堆上而不是在这个临时缓冲区(或者你使用永久缓冲区)中永久分配你想保留的任何东西。

使用这种方法时,我的性能通常比原始malloc / new好10倍。