当前位置:嗨网首页>书籍在线阅读

14-尽量减少动态内存空间分配

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.11.1 尽量减少动态内存空间分配

考虑到性能,我们的C++代码的最关键部分显然是display()函数。这是在任何动画或实时渲染过程中重复调用的函数,因此在此函数中(或在它调用的任何函数中)我们必须努力实现最高的效率。

将display()函数的开销保持在最低限度的一个重要方法是避免任何需要内存分配的步骤。因此,明显要避免的事情的例子包括:

  • 实例化对象;
  • 声明变量。

如果读者回顾我们迄今为止开发的程序,可以观察到,我们实际上在调用display()函数之前就已经声明了display()函数中使用到的每个变量,并分配了它的空间。声明或实例化几乎从不出现在display()函数中。例如,程序4.1在它开头包含以下代码块:

// 分配在display()函数中使用的变量空间,这样它们就不必在渲染过程中分配
GLuint mvLoc, projLoc;
int width, height;
float aspect;
glm::mat4 pMat, vMat, mMat, mvMat;

请注意,我们故意在代码块的顶部放了一个注释,说明这些变量是预先分配的,以便稍后在display()函数中使用(尽管我们到现在才明确地指出这一点)。

在我们的矩阵堆栈示例中发生了一个未预先分配的变量的情况。使用C++堆栈类,每次“推”操作都会导致动态内存分配。有趣的是,在Java中,JOML库提供了一个与OpenGL一起使用的MatrixStack类,它允许为矩阵堆栈预先分配空间!我们在本书的Java版中使用它。

还有其他更微妙的例子。例如,将数据从一种类型转换为另一种类型的函数调用在某些情况下可能会实例化并返回新转换的数据。因此,理解从display()调用的任何库函数的行为非常重要。数学库GLM并没有专门针对速度优化设计。这导致一些操作可能引起动态内存分配。如果可能的话,我们会尽量使用直接在已经分配了空间的变量上操作的GLM函数。我们鼓励读者在性能至关重要时探索替代方法。