【问题标题】:Is it better to have multiple arrays or one multi-dimensional array?拥有多个数组还是一个多维数组更好?
【发布时间】:2011-05-12 04:24:20
【问题描述】:

我正在做一个项目,我必须在 PHP 中对数据数组执行计算。其中一些计算涉及使用多个数组。都是相同的长度(计数)。

问题:将数据放入多维数组还是保存在两个数组中更有效(内存和处理器使用率)。

请记住,其中一些数组可能有数千个值。

示例:为了更好地说明,以下是数据和用法的示例:

X = 1,2,3,4,5

Y = 2,3,3,4,4

计算 X 和 Y 之间的相关性。

为此:

  1. 从列中获取 X 和 Y 的总和
  2. 从列中获取 X^2 和 Y^2 的总和
  3. 然后用相关公式计算

我的想法: 将两个数组组合成一个多维数组可以减少计算的迭代次数,但需要先将它们组合起来。

所以我主要关心和询问的原因是创建多维数组并对其进行 1 次迭代是否需要更少的资源,或者将它们分开并迭代每个数组是否更好 - 进行 2 次迭代。

或者有没有更好的方法在不涉及迭代的数组上执行计算?

【问题讨论】:

  • 在 PHP 中担心 CPU 和内存效率是弄巧成拙的。如果您的数组变得足够大而成为一个问题,那么您不应该使用 PHP。也就是说,答案取决于您最受限制的资源:CPU 还是内存。您可能远未达到两者的极限,因此没有必要担心。
  • 这个项目在 RackSpace 云上,所以我按 CPU 周期计费 - 处理器时间和磁盘 I/O 的集合(以每月 10,000 次为基础)。因此,我想尽量减少应用程序使用的资源量。希望它会保持在这个限制之下,但有些数组很大。

标签: php arrays


【解决方案1】:

如果您已经将数据作为两个单独的数组,那么首先合并它们会浪费时间和资源。

在 PHP 中有两种形式的数组访问,迭代,它使用内部指针并被顺序访问,以及通过关联的键/索引,这是一个哈希映射而不是顺序。如果您要查看数组的所有元素并且可以按顺序进行,请尝试使用内置的 array_ 函数或迭代器函数 reset()、next()、cur() 迭代地访问它, end(), each()。

看看 PHP 中的array_reduce() 函数,它可以帮助你快速实现这种事情。尽管在这种简单的情况下,您可能最好直接执行 for() 循环并使用数组迭代器函数 reset()、next()、cur() 从每个数组中获取值 - 或者如果它们的键控相同,您可以只执行一个 foreach() 并将其中的密钥用于另一个。

$sum_x = array_reduce($x, create_function('$x1,$x2', 'return $x1 + $x2;'), 0);
$sum_y = array_reduce($y, create_function('$y1,$y2', 'return $y1 + $y2;'), 0);
$sum_x2 = array_reduce($x, create_function('$x1,$x2', 'return $x1 + $x2 * $x2;'), 0);
$sum_y2 = array_reduce($y, create_function('$y1,$y2', 'return $y1 + $y2 * $y2;'), 0);

$sum_x = 0;
$sum_y = 0;
$sum_x2 = 0;
$sum_y2 = 0;

foreach (array_keys($x) as $i) {
  $sum_x += $x[$i];
  $sum_y += $y[$i];
  $sum_x2 += $x[$i] * $x[$i];
  $sum_y2 += $y[$i] * $y[$i];
}

【讨论】:

  • array_ 方法及其回调函数确实非常有用——我经常使用它们。特别是array_map()。作为一个习惯于像 F#、Haskell、JS(至少是 jQuery)这样的函数式语言的程序员,我已经习惯了像这样使用匿名函数内联的奢侈,所以 create_function() 很有帮助。
  • 谢谢。这是一个很大的帮助。
【解决方案2】:

考虑到 PHP 中的所有数组都是哈希表并且是关联的,我想最大的性能提升将是更少的迭代。我会使用多维数组。

【讨论】:

  • PHP 确实将所有数组存储为关联数组,但它们都具有独立于关联索引的内部排序。因此,如果您通过数组迭代器顺序处理数组,这将比任何关联查找都快。
【解决方案3】:

写一个测试用例?您可以使用 PEAR 来确定:http://pear.php.net/package/Benchmark

【讨论】:

  • 谢谢。在我完成核心部分之后,我很可能会这样做。
【解决方案4】:

这不是 PHP 特定的。 Locality of reference 数据通常很重要,因为缓存未命中很昂贵。

例如,如果您正在处理并行数组中的项目(全部为?1,然后全部为?2...),将它们组织在内存中会更有效:

A1 B1 C1 ... A2 B2 C2 ... A3 B3 C3 ...

而不是典型的:

A1 A2 A3 ... B1 B2 B3 ... C1 C2 C3 ...

当然,这取决于您的具体计算。将数据加载到第一个布局中可能需要相当长的时间。最后,剖析是唯一确定的方法。

【讨论】:

    【解决方案5】:

    我看不出一个二维数组或两个一维数组在处理器或内存方面会有什么不同。应该使用相同数量的内存。它们是否将具有相同的数字或元素?

    【讨论】:

    • 这也是我的第一个想法。但这不一定是真的 - 基于数组在迭代中的存储和访问方式。
    猜你喜欢
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 2011-07-09
    • 2012-01-03
    相关资源
    最近更新 更多