如果我使用分配的内存手(GBS):C++分配内存缺点?
int N = ...;
int * array_ = new int[N];
并应用阵,这种方法有什么样的缺点的一小部分,不是明显的事实外,我在浪费内存?它会影响CPU性能还是会使程序不稳定?
这背后的原因是为了避免使用矢量类,因为在激烈的应用程序中性能大打击。
如果我使用分配的内存手(GBS):C++分配内存缺点?
int N = ...;
int * array_ = new int[N];
并应用阵,这种方法有什么样的缺点的一小部分,不是明显的事实外,我在浪费内存?它会影响CPU性能还是会使程序不稳定?
这背后的原因是为了避免使用矢量类,因为在激烈的应用程序中性能大打击。
根据如何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]);
对,我的坏。我完全读错了。 –
唯一真正可靠的方法就是通过实际操作并运行性能测试。试着用你想的所有方式去做,根据这些真实测试记录的实际数据进行比较和对比。但是,除此之外,一个有教养的猜测会是你高估了std::vector
的性能。
并使用数组的一小部分,这种方法有什么样的缺点,除了显而易见的事实,我浪费内存?它会影响CPU性能还是会使程序不稳定?
您的代码将难以维护和异常不安全。 (是的,它会的。不,真的)
背后的原因是避免使用矢量类,因为在激烈的应用程序中性能大打击。
这在C++的任何可敬的实现中都是错误的。 std::vector
具有零开销。编译器比你更擅长优化,并且可以内联成员函数和其他东西。
关于你的评论:
那么,它给因为添加新项目时的矢量类将所有阵列数据到一个新的数组,然后删除旧的阵列。基准测试显示至少有50%的命中率,在某些情况下为100%。
+1 for“在任何可执行的C++中。std :: vector没有任何开销。编译器比你更优化” – deeiip
“std :: vector'具有零开销”在这个用例中是错误的。我的答案包含大量开销的描述。 –
这已经解决了here。
这里是答案:
它始终是更好地使用std ::矢量/的std ::阵列,至少要等到你 可以确证(通过分析)的T * A =新T [100]; 解决方案在您的特定情况下速度更快。这是 不太可能发生:vector/array是围绕 普通旧数组的极薄层。有一些开销与边界检查 vector :: at,但你可以通过使用运算符[]来规避。
的理由背后,是避免使用向量类,由于密集的应用的大的性能损失。
据我所知,使用向量没有大的性能影响。除非你可以更具体,否则你的整个论点是无效的(即你应该使用向量)。
虽然可能会有不良使用矢量的性能开销(问题不在于矢量,而是您的客户端代码)。如果你确实使用vector,考虑使用reserve。否则,请尝试使用std :: forward_list或std :: list(如果您需要不一致地添加元素)。
矢量不会导致大规模的性能下降 – deeiip
为什么不比较你的方法和使用矢量? – Sash
好吧,它给出了,因为当添加一个新的项目时,向量类将所有的数组数据复制到一个新的数组,然后删除旧的数组。基准测试显示至少有50%的命中率,在某些情况下为100%。 – SkyRipper