быстрее использовать array_keys() в foreach statemnt или установить переменную значения, которая никогда не использовалась?

Предположим, я хочу перебирать массив и либо никогда не смотрю на значения, либо устанавливаю в них вещи, поэтому мне нужны только ключи. Что быстрее:

// Set a variable each iteration which is unused.
foreach ($array as $key => $value) {
  $array[$key]['foo'] = 'bar';
}

// Call array_keys() before iterating.
foreach (array_keys($array) as $key) {
  $array[$key]['foo'] = 'bar';
}

Ответ 1

Я думаю, что это также сработает и может быть быстрее:

foreach ($array as &$value) {
  $value['foo'] = 'bar';
}

UPDATE: Я сделал небольшой тест, и кажется, что это быстрее. http://codepad.org/WI7Mtp8K

Ответ 2

Оставляя в стороне, что второй пример надуман. Смысл, как заметил Эшли Бэнкс, зачем вы это делаете?

Первый пример был бы более результативным из двух. Второй имеет накладные расходы на дополнительный вызов функции array_keys().

Ознакомьтесь с PHP Benchmark для дополнительных тестов производительности. Если у вас есть сомнения, сравните его с помощью microtime().

Ответ 3

Люди должны перестать уделять приоритетное внимание вопросу мотивов ОП.

Я сделал простой тест на микро-время и заметил едва заметную разницу во времени выполнения.

Метод - создание тестового массива:

$arr = array();
for($i = 0; $i<10000; $i++){
    $arr[] = mt_rand(0, PHP_INT_MAX);
    //NOTE: I also tested setting values in random keys, no measurable difference
}

Затем используйте этот массив для тестирования:

//Method 1
$start = microtime(true);
foreach(array_keys($arr) as $k){
    $arr[$k] = 0; //Do something
}
$end = microtime(true);
echo 'we spent '.($end - $start).' seconds doing this.';

Вот код для тестирования другого метода (выполнялся отдельно или результаты менялись еще больше)

//Method 2
$start = microtime(true);
foreach($arr as $k => $v){
    $arr[$k] = 0; //Do something
}
$end = microtime(true);
echo 'we spent '.($end - $start).' seconds doing this.';

Мои тайминги составляли около 2 миллисекунд времени исполнения для обоих. Я полагаю, что моя система недостаточно стабильна для последовательных мер микросекунд. Я не мог определить, был ли он быстрее, чем другой.

Я также тестировал запуск каждого foreach 1000 раз с меньшим массивом для измерения самого метода, но у меня был тот же результат в 2 миллисекунды.

Так что это значит? Основываясь на этих простых тестах, выбор метода бессмыслен в отношении производительности. Может быть, вы можете измерить небольшое улучшение с помощью одного метода над другим, если вы используете чрезвычайно большие массивы на чрезвычайно стабильных системах или запускаете очень много foreach-петель в одном направлении.