2013-12-12 57 views
-1

如果我使用分配的内存手(GBS):C++分配内存缺点?

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

并应用阵,这种方法有什么样的缺点的一小部分,不是明显的事实外,我在浪费内存?它会影响CPU性能还是会使程序不稳定?

这背后的原因是为了避免使用矢量类,因为在激烈的应用程序中性能大打击。

+2

矢量不会导致大规模的性能下降 – deeiip

+0

为什么不比较你的方法和使用矢量? – Sash

+0

好吧,它给出了,因为当添加一个新的项目时,向量类将所有的数组数据复制到一个新的数组,然后删除旧的数组。基准测试显示至少有50%的命中率,在某些情况下为100%。 – SkyRipper

回答

5

根据如何OS和(也许)程序响应内存不足的情况,浪费内存可能使程序速度变慢或不稳定。没有保证。

在现代操作系统上,一个大但未使用的动态数组int应该只有很小的影响或没有影响。大多数未使用的阵列部分只会被分配虚拟内存空间,它永远不会被RAM或交换支持。 64位操作系统(如果你谈论的是32GB内存,你必须使用这个操作系统)不会缺少虚拟地址空间,除非你使用了这些东西。

背后的原因是为了避免使用矢量类,由于 在激烈的应用程序中的大性能。

创建大于您所需的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]); 
+0

对,我的坏。我完全读错了。 –

0

唯一真正可靠的方法就是通过实际操作并运行性能测试。试着用你想的所有方式去做,根据这些真实测试记录的实际数据进行比较和对比。但是,除此之外,一个有教养的猜测会是你高估了std::vector的性能。

4

并使用数组的一小部分,这种方法有什么样的缺点,除了显而易见的事实,我浪费内存?它会影响CPU性能还是会使程序不稳定?

您的代码将难以维护和异常不安全。 (是的,它会的。不,真的)

背后的原因是避免使用矢量类,因为在激烈的应用程序中性能大打击。

这在C++的任何可敬的实现中都是错误的。 std::vector具有零开销。编译器比你更擅长优化,并且可以内联成员函数和其他东西。


关于你的评论:

那么,它给因为添加新项目时的矢量类将所有阵列数据到一个新的数组,然后删除旧的阵列。基准测试显示至少有50%的命中率,在某些情况下为100%。

请参阅std::vector::reserve

+0

+1 for“在任何可执行的C++中。std :: vector没有任何开销。编译器比你更优化” – deeiip

+1

“std :: vector'具有零开销”在这个用例中是错误的。我的答案包含大量开销的描述。 –

0

这已经解决了here

这里是答案:

它始终是更好地使用std ::矢量/的std ::阵列,至少要等到你 可以确证(通过分析)的T * A =新T [100]; 解决方案在您的特定情况下速度更快。这是 不太可能发生:vector/array是围绕 普通旧数组的极薄层。有一些开销与边界检查 vector :: at,但你可以通过使用运算符[]来规避。

0

的理由背后,是避免使用向量类,由于密集的应用的大的性能损失。

据我所知,使用向量没有大的性能影响。除非你可以更具体,否则你的整个论点是无效的(即你应该使用向量)。

虽然可能会有不良使用矢量的性能开销(问题不在于矢量,而是您的客户端代码)。如果你确实使用vector,考虑使用reserve。否则,请尝试使用std :: forward_list或std :: list(如果您需要不一致地添加元素)。