我最近涉足图形编程,并且注意到许多图形引擎(即Ogre)和许多编码器都更喜欢动态地初始化类实例。这是Ogre Basic Tutorial 1的示例
//...
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
//...
然后将
ogreHead
和headNode
数据成员和方法称为ogreHead->blabla
。为什么要搞乱对象指针而不是普通对象?
顺便说一句,我还在某处读到堆内存分配比堆栈内存分配慢得多。
最佳答案
堆分配不可避免地要比栈分配慢得多。更多关于“慢多少?”后来。但是,在许多情况下,出于以下几个原因,选择是“为您量身定制”:
堆比堆栈慢多少?
我们将稍等一下。
对于给定的分配,堆栈分配只是一个减法运算[1],其中最少
new
或malloc
将是一个函数调用,甚至最简单的分配器也可能是几十条指令,在复杂情况下,数千条[因为内存必须从操作系统中获取,并清除其先前的内容]。因此,从10倍到“无限”变慢的任何事物,都可以接受或接受。确切的数字将取决于代码运行的确切系统,分配的大小以及通常是“对分配器的先前调用”(例如,一长串的“释放”分配可能会使分配新对象的速度变慢,因为很合适)必须搜索)。当然,除非您使用堆管理的“鸵鸟”方法,否则还需要释放对象并应对“内存不足”,这会增加代码/时间的执行量和代码复杂性。但是,使用一些相当聪明的编程,这几乎可以被隐藏起来-例如,在对象的整个生命周期中分配长时间保持分配状态的内容将“无须担心”。从堆中为3D游戏中的每个像素或每个三角形分配对象显然不是一个好主意。但是,如果对象的生命周期是很多帧甚至整个游戏,那么分配和释放它的时间将几乎没有。
同样,不要对10000个对象进行单独分配,而是对10000个对象进行分配。对象池就是这样一种概念。
此外,分配时间通常不是花费时间的地方。例如,从磁盘上的文件读取三角列表将比为同一三角列表分配空间要花费更长的时间-即使您分配了每个三角列表!
对我来说,规则是:
[1]如果堆栈是“朝着高地址增长”的话,或者添加-我不知 Prop 有这种架构的机器,但是这是可以想象的,而且我认为已经完成了。对于堆栈的增长方式,或者有关运行时堆栈如何工作的任何其他事项,C毫无疑问。