C++分配内存的缺点

C++ allocating memory drawbacks?

本文关键字:缺点 内存 分配 C++      更新时间:2023-10-16

如果我使用分配了很多(GB)内存

int N = ...;
int * array_ = new int[N];

使用数组的一小部分,除了明显的事实之外,这种方法还有什么缺点,我在浪费内存?它会影响cpu性能还是使程序不稳定?

这背后的原因是避免使用向量类,因为在密集的应用程序中会对性能造成很大影响。

根据操作系统和(可能)程序对低内存情况的反应,浪费内存可能会使程序变得缓慢或不稳定。没有保证。

在现代操作系统上,大型但大部分未使用的动态int阵列应该影响很小或没有影响。阵列中大多数未使用的部分将只分配虚拟内存空间,它永远不会由RAM或交换支持。64位操作系统(如果你谈论的是32GB的RAM,你必须使用它)不会缺少虚拟地址空间,直到你用掉248字节。

这背后的原因是避免使用向量类,因为在高强度的应用程序中,性能大受影响。

创建一个比您需要的大的vector<int>可能会对性能造成很大的影响,因为它将被初始化,而这个数组尚未初始化。如果这就是你的意思,那么你的代码应该不会像一个巨大的向量那样引起更多的不稳定性,而且可能会更少,因为内存永远不会被触及。

如果不是这样的话,那么在启用了优化的情况下,向量应该不会对性能造成太大的影响。因此,例如,您可以通过使用向量struct UninitializedInt { int value; UninitializedInt() {} };来解决它,以确保没有操作默认构造。您可能希望添加一个int构造函数和/或operator int(),以使用户的生活更轻松(防止到处键入.value),尽管这会导致算术运算符不明确,所以这不是一个大灌篮。

或者,您可以使用reserve()为向量分配空间,然后根据需要使用resize()push_back()insert()。如果最终你实际上检查了每次访问的边界或修改了大小,那么你当然只需要用另一个替换一个性能命中。

不过,您的代码应该可以工作。如果您不需要重新实现vector的太多接口,这可能是消除初始化开销的最简单的方法。当然,你需要确保你正确地释放它。例如:

std::unique_ptr<int[]> array_(new int[N]);

使用数组的一小部分,除了明显的事实之外,这种方法还有什么缺点,我在浪费内存?它会影响cpu性能还是使程序不稳定?

您的代码将很难维护,并且异常不安全。(是的,会的。不,真的。)

这背后的原因是避免使用向量类,因为在密集的应用程序中会对性能造成很大影响。

这在任何值得尊敬的C++实现中都是错误的。std::vector的开销为零。编译器比你更善于优化,并且可以内联成员函数等等。


关于您的评论:

这是因为当添加一个新项时,向量类会将所有数组数据复制到一个新数组中,然后删除旧数组。基准测试显示,命中率至少为50%,在某些情况下为100%。

参见std::vector::reserve

唯一真正可靠的方法是实际执行并运行性能测试。试着用你想的所有方法来做,并根据这些真实测试记录的实际数据进行比较和对比。但除此之外,一个有根据的猜测是,你大大高估了std::vector的性能命中率。

这里已经解决了这个问题。

答案是:

使用std::vector/std::array总是更好的,至少在您可以(通过分析)最终证明T*a=新T[100];解决方案在您的特定情况下要快得多。这是不太可能发生:矢量/阵列是围绕普通的老数组。使用进行边界检查会产生一些开销vector::at,但您可以通过使用运算符[]来绕过它。

这背后的原因是避免使用向量类,因为在密集的应用程序中会对性能造成很大影响。

据我所知,使用矢量并不会对性能造成很大影响。除非你能更具体,否则你的整个论点都是无效的(即你应该使用向量)。

不过,向量使用不当可能会带来性能开销(问题不在于向量,而在于客户端代码)。如果您确实使用矢量,请考虑使用保留。否则,请尝试std::forward_list或std::list(如果需要不一致地添加元素)。