这个问题似乎与XY 问题和过早优化有关。
您应该专注于编写清晰的代码,然后在必要时使用分析器执行优化。
我对内存池的理解正确吗?
不完全的。
...在堆栈上...
...在堆上...
存储持续时间与池的概念是正交的;可以将池分配为具有四种存储持续时间中的任何一种(它们是:静态、线程、自动和动态存储持续时间)。
C++ 标准不要求这些中的任何一个进入堆栈或堆;将它们全部视为进入同一个地方可能会很有用……毕竟,它们(通常)都进入硅芯片!
... 分配 ... 在运行前 ...
重要的是多个对象的分配发生在这些对象第一次使用之前(或至少不那么频繁);这样就不必分别分配每个对象。我认为这就是您所说的“运行前”。在选择分配大小时,越接近在任何给定时间所需的对象总数,过度分配造成的浪费就越少,过度调整大小造成的浪费也就越少。
但是,如果您的操作系统不是史前的,那么池的优势将很快消失。如果您在进行优化之前和之后使用分析器,您可能会看到这一点!
- 随着时间的推移,动态内存变得碎片化
对于 Windows 1.0 等幼稚操作系统来说,这可能是正确的。但是,在当今时代,具有分配存储持续时间的对象通常存储在虚拟内存中,虚拟内存会定期写入磁盘并从磁盘读取(这称为分页)。因此,碎片化的内存可以进行碎片整理,更常用的对象、函数和方法甚至可能最终合并到公共页面中。
也就是说,分页为您形成了一个隐式池(和缓存预测)!
CPU 可以比动态块更快地解析内存的静态块
虽然分配有静态存储持续时间的对象通常位于堆栈上,但这不是 C++ 标准的强制要求。完全有可能存在 C++ 实现,而是在堆上分配静态内存块。
对动态对象的缓存命中将与对静态对象的缓存命中一样快。碰巧堆栈通常保存在缓存中。你应该试着在没有堆栈的情况下编程一段时间,你可能会发现缓存有更多的堆空间!
在优化之前,您应该始终使用分析器来测量最重要的瓶颈!然后您应该执行优化,然后再次运行分析器以确保优化成功!
这不是一个独立于机器的过程!您需要优化每个实现!一种实现的优化可能是另一种实现的悲观。
如果是这样,为什么似乎不经常使用内存池?
上面描述的虚拟内存抽象与使用缓存分析器消除猜测相结合,实际上消除了池在所有情况下的用处,除了最不知情(即使用分析器)场景。