【问题标题】:Which type of array to use for large amounts of numbers?哪种类型的数组用于大量数字?
【发布时间】:2012-02-16 08:43:13
【问题描述】:

我需要将大量 unsigned chars 和/或 ints(可能 100,000,000 及以上)存储在一个数组中。这个数组中的数字会经常进行数学运算,所以数组会经常修改,数组的长度也可能会经常变化。

我可以使用 C 或 Objective-C(或两者)。性能方面,最好使用纯 C 数组并根据需要使用 realloc,还是只使用 NSMutableArray?或者有没有人有更好的想法?

请注意性能是我最关心的问题,如有必要我愿意编写大量的重新分配代码。

另外:内存使用是一个考虑因素,但不是问题(只要它最终不会使用多个 GB)。

【问题讨论】:

  • 重新分配代码不需要很长:int *data = 0; size_t size = 0, capacity = 0; 设置一个空数组(当然也可以使用结构)。然后保证一定的容量:if (capacity < required_capacity) { size_t new_capacity = max(capacity*2, required_capacity); int *tmp = realloc(data, new_capacity*sizeof(*data)); if (!tmp) { handle error; } else { data = tmp; capacity = new_capacity; }。有些人更喜欢使用capacity*3/2,或其他一些2 的平方根的近似值,而不是加倍容量。无论哪种方式,我都省略了对环绕的基本检查。

标签: objective-c c arrays performance


【解决方案1】:

使用NSMutableArray 意味着每次您想要获取或设置数组元素的值时都会发送两个Objective-C 消息的开销。 (一条消息将元素作为对象获取,另一条消息将其值作为原始int。)消息发送比直接数组访问慢得多。

您可以使用CFMutableArray 而不是NSMutableArray,并指定让您存储裸数字而不是对象的回调。但是您仍然需要使用函数调用来获取或设置每个数组值。

如果您需要最佳性能,只需使用纯 C 数组,如果您想使用 Objective-C++,则使用 std::vector

【讨论】:

  • 如果我使用一个普通的 C 数组,关于reallocing 的最佳方式是什么?一个电话有多贵?分配比您需要的更多以节省时间更好吗?
  • 每次重新分配数组时,您需要将数组增加一个因子(乘法)而不是固定数量(加法)。例如。 newSize = oldSize * 2不是 newSize = oldSize + 100.
  • 你的数组很小。 10000 个整数不算什么。分配超出您需要的部分,并在必要时慷慨地增长。
  • @DavidHeffernan 查看我的代码,我意识到两件事:1. 我数不清。 2. 更像是 100,000,000 个数字。还很小吗?
  • @robmayoff 使用realloc 缩小数组对性能的影响有多大?
【解决方案2】:

您的阵列需要增长多少? 使用 realloc 性能不是很好。

这就是为什么我会推荐一个链接列表,因为你可以在 glib 中找到 GSList

【讨论】:

  • 链接列表在这里听起来不合适。没有随机访问。加上所有额外的杂物,访问速度很慢。在 64 位系统上,列表开销大于列表本身。
  • @DavidHeffernan 使用realloc 很好,只要您不经常这样做。如果在需要放大时将其翻倍,而不是将其缩小,它会非常快(并且可能会浪费内存)。
  • @ugoren 确实如此,这正是我的看法
【解决方案3】:

容器: C++ 怎么样? Objective-C++ 和 STL 可能是一个重点,STL 是由聪明的人制作的,在熟练的手中它实际上非常有效。不过,在任何情况下,拥有多达 100,000,000 个条目都需要一些优化技巧。

框架: 您还没有指定任务本身,是否适合使用 CoreData 或 SQLite 之类的东西?数学可以用 SQL 过程来完成。

如果你有一些,嗯,数据样本 - 像素,音频块或类似的东西,第一个很好。在大多数其他情况下,第二种方式绝对是首选。

【讨论】:

  • 没有 SQL 数据库或类似的东西。数据可能来自任何地方——它可以从文本文件中加载,或者在运行时自发产生。基本上,它通常一开始很短,然后随着更多数字的增加和数学运算的执行而变得越来越大。
  • 我会选择 STL。 std::vector 足够聪明,可以避免每次推送时重新分配,STL 允许使用函子处理数据,内联结果快速代码。总的来说,它值得一试,而且(恕我直言)优于 Objective-C 和普通 C 数组。
  • 使用标准 C++ 容器的另一个优点是,如果内存碎片确实会导致问题(正如 David Heffernan 在评论 rob mayoff 的回答中所指出的那样),那么修复它的“优化技巧”通常是微不足道的-- 只需从std::vector 切换到std::deque
猜你喜欢
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多