Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中正确循环数组键_Php_Arrays_Performance_Loops_Coding Style - Fatal编程技术网

如何在PHP中正确循环数组键

如何在PHP中正确循环数组键,php,arrays,performance,loops,coding-style,Php,Arrays,Performance,Loops,Coding Style,如果我有一个包含多个键和值的数组,就像这样 $array = array( 'key1' => 'value1', 'key2' => 'value2', ); 当我只使用键时,是否有任何标准如何在数组中循环? 解决方案1: foreach(array_keys($array) as $array_key) { echo $array_key; } 解决方案2: foreach($array as $array_key => $array_value) {

如果我有一个包含多个键和值的数组,就像这样

$array = array(
  'key1' => 'value1',
  'key2' => 'value2',
);
当我只使用键时,是否有任何标准如何在数组中循环? 解决方案1:

foreach(array_keys($array) as $array_key) {
  echo $array_key;
}
解决方案2:

foreach($array as $array_key => $array_value) {
  echo $array_key;
}

我可以看到解决方案1的优势,因为它不调用未使用的变量
$array\u value
这两种方法在性能上有什么不同吗?有什么标准吗?

根据我快速而肮脏的基准测试,我做了以下50次:

解决方案1(最差):

阵列大小:1000000

  • 最小值:
    0.11363291740417
  • 平均值:
    0.1168146287903
  • 最大值:
    0.14569497108459
阵列大小:9999999

  • 最小值:
    1.3098199367523
  • 平均值:
    1.3250577354431
  • 最大值:
    1.3673560619354

解决方案2(中间):

阵列大小:1000000

  • 最小值:
    0.10167503356934
  • 平均值:
    0.10356130123138
  • 最大值:
    0.11027193069458
阵列大小:9999999

  • 最小值:
    1.20777870368958
  • 平均值:
    1.2256314325333
  • 最大值:
    1.2829539775848
解决方案3(最佳):

阵列大小:1000000

  • 最小值:
    0.090911865234375
  • 平均值:
    0.092938437461853
  • 最大值:
    0.097810983657837
阵列大小:9999999

  • 最小值:
    1.0793349742889
  • 平均值:
    1.0941110134125
  • 最大值:
    1.1402878761292

因此,如果只想查看数组键,可以看到解决方案3是最快的选项:)

希望这有帮助


代码:


“这两者之间的性能是否有差异?”这将非常容易测试。我认为解决方案2会更快,因为在解决方案1中,您正在调用
数组_键()
在循环的每一次迭代中。我认为这会产生多大的差异,这在很大程度上取决于数组的大小。根据@iainn的评论,对foreach和copy/no copy的更为成熟的回应:@GrumpyCrouton这可能有助于解释为什么数组_键只被调用一次:这真的很酷。这正是我要搜索的。在原始数组中循环与拆分数组键然后循环之间有很大的区别。我一直认为在阵列中循环的经典方法是最快的。我知道这是非常古老的方法,但上天禁止有人使用它。解决方案3不是最好的。它为密钥数组分配RAM,而您的测试不包括这样做的时间,也不包括取消分配新数组使用的RAM的时间(解决方案1隐式地包括)。解决方案2是最好的。
foreach (array_keys($array) as $array_key) {
  echo $array_key;
}
foreach ($array as $array_key => $array_value) {
  echo $array_key;
}
$array_keys = array_keys($array);
foreach ($array_keys as $array_key) {
  echo $array_key;
}
<?php
class DirtyBenchmarker {
  private $results = [];
  private $size_of_array;

  public function __construct($size_of_array)
  {
    $this->size_of_array = $size_of_array;
    echo 'Size of array: ' .  $this->size_of_array . PHP_EOL;
  }

  private function solution1() {
    $array = range(0, $this->size_of_array - 1);
    ob_start();
    $start = microtime(true);
    foreach (array_keys($array) as $array_key) {
      echo $array_key;
    }
    $finish = microtime(true) - $start;
    $echod = ob_get_clean();
    $this->results['solution1'][] = $finish;
  }

  private function solution2() {
    $array = range(0, $this->size_of_array - 1);
    ob_start();
    $start = microtime(true);
    foreach ($array as $array_key => $array_value) {
      echo $array_key;
    }
    $finish = microtime(true) - $start;
    $echod = ob_get_clean();
    $this->results['solution2'][] = $finish;
  }

  private function solution3() {
    $array = range(0, $this->size_of_array - 1);
    $array_keys = array_keys($array);
    ob_start();
    $start = microtime(true);
    foreach ($array_keys as $array_key) {
      echo $array_key;
    }
    $finish = microtime(true) - $start;
    $echod = ob_get_clean();
    $this->results['solution3'][] = $finish;
  }

  public function benchmark() {
    $this->solution1();
    $this->solution2();
    $this->solution3();
  }

  public function getResults()
  {
    echo PHP_EOL . 'Solution 1:' . PHP_EOL;
    echo 'Min: ' . min($this->results['solution1']) . PHP_EOL;
    echo 'Avg: ' . array_sum($this->results['solution1']) / count($this->results['solution1']) . PHP_EOL;
    echo 'Max: ' . max($this->results['solution1']) . PHP_EOL;

    echo PHP_EOL . 'Solution 2:' . PHP_EOL;
    echo 'Min: ' . min($this->results['solution2']) . PHP_EOL;
    echo 'Avg: ' . array_sum($this->results['solution2']) / count($this->results['solution2']) . PHP_EOL;
    echo 'Max: ' . max($this->results['solution2']) . PHP_EOL;

    echo PHP_EOL . 'Solution 3:' . PHP_EOL;
    echo 'Min: ' . min($this->results['solution3']) . PHP_EOL;
    echo 'Avg: ' . array_sum($this->results['solution3']) / count($this->results['solution3']) . PHP_EOL;
    echo 'Max: ' . max($this->results['solution3']) . PHP_EOL;
  }
}

$benchmarker = new DirtyBenchmarker(1000000);
$runs = 50;
for ($i = 0; $i < $runs; $i++) {
  $benchmarker->benchmark();
}
$benchmarker->getResults();

$benchmarker = new DirtyBenchmarker(9999999);
$runs = 50;
for ($i = 0; $i < $runs; $i++) {
  $benchmarker->benchmark();
}
$benchmarker->getResults();