В PHP (> = 5.0) быстрее проходит ссылка?

В PHP параметры функции могут передаваться по ссылке, добавляя амперсанд к параметру в объявлении функции, например:

function foo(&$bar) { // ... } 

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

Вместо этого PHP, похоже, использует Copy On Write, чтобы избежать копирования объектов (а может быть и массивов) до тех пор, пока они не будут изменены. Таким образом, для функций, которые не изменяют свои параметры, эффект должен быть таким же, как если бы вы передали их по ссылке.

Тем не менее, мне было интересно, может ли логика «Копировать по записи» коротко укорачиваться при передаче по ссылке и влияет ли это на производительность.

ETA: Конечно, я предполагаю, что это не быстрее, и я хорошо знаю, что это не то, на что ссылаются. Поэтому я думаю, что мои собственные догадки неплохие, я просто ищу ответ от кого-то, кто действительно знает, что конкретно происходит под капотом. В течение пяти лет разработки PHP мне всегда было трудно получить качественную информацию о внутренних PHP-функциях, не читающих источник.

Solutions Collecting From Web of "В PHP (> = 5.0) быстрее проходит ссылка?"

Zend Engine использует copy-on-write, и когда вы используете ссылку самостоятельно, она берет на себя дополнительные дополнительные накладные расходы. Можете только найти это упоминание в момент написания, но комментарии в руководстве содержат другие ссылки.

(EDIT) На странице руководства по объектам и ссылкам содержится немного больше информации о том, как переменные объекта отличаются от ссылок.

В тесте с 100 000 итерациями вызова функции с строкой 20 кБ результаты:

Функция, которая просто считывает / использует параметр

 pass by value: 0.12065005 seconds pass by reference: 1.52171397 seconds 

Функция для записи / изменения параметра

 pass by value: 1.52223396 seconds pass by reference: 1.52388787 seconds 

Выводы

  1. Передача параметра по значению всегда быстрее

  2. Если функция меняет значение переданной переменной, для практических целей это то же самое, что передавать по ссылке, чем по значению

Я провел некоторое испытание на этом, потому что я был не уверен в ответах.

Мои результаты показывают, что передача больших массивов или строк по ссылке IS значительно быстрее.

Вот мои результаты: эталонный тест

Ось Y (Runs) – это сколько раз функция могла быть вызвана за 1 секунду * 10

Тест повторялся 8 раз для каждой функции / переменной

И вот переменные, которые я использовал:

 $large_array = array_fill(PHP_INT_MAX / 2, 1000, 'a'); $small_array = array('this', 'is', 'a', 'small', 'array'); $large_object = (object)$large_array; $large_string = str_repeat('a', 100000); $small_string = 'this is a small string'; $value = PHP_INT_MAX / 2; 

Это следующие функции:

 function pass_by_ref(&$var) { } function pass_by_val($var) { } 

Я почти уверен, что нет, это не быстрее. Кроме того, в руководстве конкретно говорится о том, чтобы не использовать ссылки для повышения производительности.

Редактировать: Не могу найти, где это сказано, но оно есть!

Я экспериментировал со значениями и ссылками строки длиной 10 Кбайт, передавая его двум идентичным функциям. Один принимает аргумент по значению, а второй – по ссылке. Они были общими функциями – принимать аргументы, выполнять простую обработку и возвращать значение. Я сделал 100 000 звонков обоих и выяснил, что ссылки не предназначены для повышения производительности – прибыль от ссылки составляет около 4-5%, и она растет только тогда, когда строка становится достаточно большой (100 тыс. И более, что дает улучшение на 6-7%), , Итак, мой вывод – не использовать ссылки для увеличения производительности, этот материал не для этого.

Я использовал PHP Version 5.3.1

Нет ничего лучше тестового фрагмента кода

 <?PHP $r = array(); for($i=0; $i<500;$i++){ $r[]=5; } function a($r){ $r[0]=1; } function b(&$r){ $r[0]=1; } $start = microtime(true); for($i=0;$i<9999;$i++){ //a($r); b($r); } $end = microtime(true); echo $end-$start; ?> 

Конечный результат! Чем больше массив (или чем больше количество вызовов), тем больше разница. Поэтому в этом случае вызов по ссылке быстрее, потому что значение изменяется внутри функции.

В противном случае нет никакой реальной разницы между «по ссылке» и «по значению», компилятор достаточно умен, чтобы не создавать новую копию каждый раз, если в этом нет необходимости.

При передаче объектов нет необходимости добавлять & operator. В PHP 5+ объекты все равно передаются по ссылке.