массив_карта против цикла и операции - PullRequest
35 голосов
/ 06 декабря 2011

Использование:

for($i=1; $i<= 10000; ++$i) {
    $arrayOfNumbers[] = rand(1, 99999);
}

Может ли кто-нибудь объяснить, почему существует такая разница в скорости:

array_map(array($maxHeap, 'insert'), $arrayOfNumbers);
# Avg Time: 0.92856907844543s

# against

foreach($arrayOfNumbers as $number) {
    $maxHeap->insert($number);
}
# Avg Time: 1.3148670101166

$maxHeap являющийся объектом class MaxHeap extends SplMaxHeap

Ответы [ 2 ]

14 голосов
/ 09 апреля 2013

Насколько мне известно, php ничего не делает асинхронно, в отличие от ответа Саджита Аммы.

Я подозреваю, что это на самом деле из-за различий в поиске $maxHeap->insert.

С помощью цикла foreach, который вы вызываете $maxHeap->insert в текущей области, интерпретатор php должен искать maxHeap, а затем искать insert в экземпляре maxHeap.В рамках скрипта, который вы запускаете, могут быть другие переменные, которые могут замедлить поиск.

С array_map интерпретатор php знает, что будет вызывать точно такой же $maxHeap->insert, он может сделатьпоиск только один раз и использовать тот же «кодовый адрес» для остальных итераций.

2 голосов
/ 16 декабря 2011

Это происходит из-за разницы между функциями обратного вызова и обычными функциями.

Во второй итерации массива с использованием foreach каждая итерация вызывает функцию "вставки" и ожидает выполнения (управление возвратом функции)и перейти к следующей итерации.

Но в функции array_map функция "вставка" происходит как функция обратного вызова, она вызывает "вставку" и не ждет результата и вызывает вставку со следующим элементом в массиве.Так что это быстрее.

Надеюсь, это поможет.

...