堆栈更喜欢堆?

Pil*_*pel 2 c++ class object

我最近进入图形编程,我注意到许多图形引擎(即Ogre)和许多编码器总体上更喜欢动态地初始化类实例.这是Ogre Basic Tutorial 1的一个例子

//...

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");

//...
Run Code Online (Sandbox Code Playgroud)

ogreHead然后将headNode数据成员和方法称为ogreHead->blabla.

为什么要乱用对象指针而不是普通对象?

顺便说一下,我还读到了堆内存分配比堆栈内存分配慢得多的地方.

Mat*_*son 5

堆分配不可避免地比堆栈分配慢得多.更多关于"慢多少?" 后来.但是,在许多情况下,选择是"为你做的",原因如下:

  1. 堆栈有限.如果你用完了,应用程序几乎总是被终止 - 没有真正好的恢复,甚至打印错误消息说"我跑出堆栈"可能很难......
  2. 当您离开进行分配的功能时,堆栈分配"消失".
  3. 可变性更加明确,易于处理.C++不能很好地处理"可变长度数组",并且肯定不能保证在所有编译器中都能工作.

堆栈堆栈速度慢多少?

我们会稍微谈谈"而且重要".

对于给定的分配,堆栈分配只是一个减法运算[1],其中最小newmalloc将是一个函数调用,甚至最简单的分配器可能是几十个指令,在复杂情况下数千[因为内存必须从操作系统中获取,并清除它以前的内容].所以从10倍到"无限"慢的任何东西,给予或接受.确切的数字将取决于运行代码的确切系统,分配的大小,以及通常"以前对分配器的调用"(例如,"释放"分配的长列表可能会使分配新对象变慢,因为它非常适合必须搜索).当然,除非你执行堆管理的"鸵鸟"方法,否则你还需要释放对象并应对"内存不足",这会增加执行代码/时间和代码的复杂性.

然而,通过一些相当聪明的编程,这可能基本上是隐藏的 - 例如,在对象的生命周期内分配长时间保持分配的东西,将"无需担心".对于3D游戏中的每个像素或每个三角形,从堆中分配对象将是一个坏主意.但是如果对象的生命周期是很多帧甚至整个游戏,那么分配和释放它的时间几乎为零.

类似地,不是进行10000个单独的对象分配,而是为10000个对象创建一个.对象池就是这样一个概念.

此外,分配时间通常不是花费时间的地方.例如,从磁盘中读取文件中的三角形列表所花费的时间比为同一个三角形列表分配空间要长得多 - 即使您分配了每个单独的三角形列表!

对我来说,规则是:

  1. 它是否适合堆叠?通常几千字节很好,很多千字节不太好,兆字节绝对不行.
  2. 数字(例如,对象数组)是否已知,以及最大值是否可以将其放入堆栈中?
  3. 你知道对象会是什么吗?换句话说,可能需要在堆上分配抽象/多态类.
  4. 它的寿命是否与它的范围相同?如果没有,请使用堆(或进一步向下堆栈,并将其传递给堆栈).

[1]或者添加堆栈是否"向高地址增长" - 我不知道具有这种架构的机器,但可以想象,我认为已经有一些.对于堆栈增长的方式,或者关于运行时堆栈如何工作的其他任何方式,C当然不做任何承诺.