【问题标题】:array_merge VS direct array injection performancearray_merge VS 直接数组注入性能
【发布时间】:2019-07-25 00:26:21
【问题描述】:

它们之间在性能或任何方面有什么不同吗?

$a = ['a' => 1, 'b' => 2, 'c' => 3];
$b = ['d' => 4, 'e' => 5, 'f' => 6];
$c = array_merge($a, $b);

VS

$a = [];
$a['a'] = 1;
$a['b'] = 2;
$a['c'] = 3;

$b = [];
$b['d'] = 4;
$b['e'] = 5;
$b['f'] = 6;
$c = array_merge($a, $b);

VS

$a = [];
$a = ['a' => 1, 'b' => 2, 'c' => 3];
$a['d'] = 4;
$a['e'] = 5;
$a['f'] = 6;

【问题讨论】:

  • IMO 这不是一个好问题。如果你想知道性能,你可以自己编写基准测试代码。很明显array_merge是一个函数,它合并了相同的键,所以它比刚刚阅读手册的方括号语法更复杂。

标签: php arrays multidimensional-array query-performance


【解决方案1】:

首先,除非您需要处理大量请求或非常大的数据集,否则像这样的微优化通常是没有意义的。话说……

选项 1 和选项 2 的性能应该大致相同。但是,第一个选项会稍微快一些,因为不需要动态扩展数组 A 和数组 B,这在第二个示例中是必需的。

但是,前两个示例都使用了array_merge(),这引入了实际进行函数调用的开销,并且仍然检查密钥是否实际存在。请注意,array_merge 会在与字符串键关联的元素已存在时覆盖该元素。但是请记住,对于带有数字键的元素,这不是这样做的。在这种情况下,没有这样的检查并且没有任何内容被覆盖;键和元素只是简单地附加到目标数组的末尾。以下是 PHP 文档说明:

如果输入数组具有相同的字符串键,则该键的后一个值将覆盖前一个值。但是,如果数组包含数字键,则后面的值不会覆盖原始值,而是会被追加。带有数字键的输入数组中的值将使用从结果数组中的零开始的递增键重新编号。 https://www.php.net/manual/en/function.array-merge.php

当然,使用array_merge() 的好处是你可以一眼就知道它做了什么。

这是我的基准,它比较了将 $b 的项目直接插入 $a 与合并 $a$b 以使用 array_merge() 创建一个新数组。两个初始数组中都有 100 万个项目。

<?php


$a = [];
$b = [];

/*Insert 1000000 elements into array $a with string keys starting at '0' and ending at '999999'*/
for ($i = 0; $i < 1000000; $i++)
{
  $a["{$i} "] = $i;
}

/*Insert 1000000 elements into array $b with string keys starting at '1000000' and ending at '1999999' */
for ($j = 1000000; $j < 2000000; $j++)
{
  $b["{$j} "] = $j;
}


$temp = $a;

/*Inserting the values of $b into $temp in a loop*/
$start = microtime(true);
foreach($b as $key => $current)
{
   $temp[$key] = $current;  
}   

$end = microtime(true);
$runtime = $end - $start;
$output =  "<p>Inserted elements of array a and b with assignment in %.10f ({$runtime}) seconds</p>";

echo sprintf($output, $runtime);



/*Using array_merge to merge $a and $b */   
$start = microtime(true);

$c = array_merge($a, $b);

$end = microtime(true);


$runtime = $end - $start;
$output =  "<p>Merged array a and b with array_merge() in %.10f  ({$runtime}) seconds </p>";

echo sprintf($output, $runtime);

输出:

在 0.1125514507 (0.11255145072937) 秒内插入数组 a 和 b 的元素

使用 array_merge() 在 0.0289690495 (0.028969049453735) 秒内合并数组 a 和 b。

我修改了基准,因此它在分配测试中使用了一个临时数组,因此 $a 和 $b 永远不会被修改。但是,运行时间的差异仍然存在。为了得到一个好的平均值,我运行了 1000 次,取两次运行时间的平均值。最终的结果与最初的运行并没有太大的不同。第一种方法的平均时间约为 0.1012 秒,而merge_array() 方法的平均时间为 0.0574 秒。相差大约 0.0438 秒或 43.8 毫秒。

因此,您看到的平均性能差异约为 57%。这很有趣,因为我发现 array_merge() 在旧版本的 PHP 中运行缓慢。但是,从 7.3 开始,看起来应该选择 array_merge(),而不是手动将数组与字符串键合并。

【讨论】:

  • 感谢您提供非常详细的答案,并提供了一个非常有助于证明此类实施的基准。该数组将包含大约 5-20 个键值对,所以我会很大。在性能方面差别不大,我想我会选择选项 A 来提高代码的可读性。使用选项 C 对具有 50 个 KVP 的数组进行成像,这样读取会很麻烦。
猜你喜欢
  • 2011-02-25
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 2015-11-23
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
相关资源
最近更新 更多